鏈式棧介面設計
/**
* @file name: 鏈式棧介面設計
* @brief
* @author ni456xinmie@163.com
* @date 2024/04/24
* @version 1.0 :版本
* @property :類比於順序棧,鏈式棧也有一個棧頂和棧底。根據鏈式表特性,將第一個插入的值作為棧底,即尾節點作為棧底。首節點作為棧頂。
* @note
* CopyRight (c) 2023-2024 ni456xinmie@163.com All Right Reseverd
*/
功能函式:構造鏈式結點
typedef int DataType_t; // 指的是鏈式棧中的結點有效資料型別
typedef struct LinkStack // 構造結點,連結串列中所有結點的資料型別應該是相同的
{
DataType_t data; // 結點的資料域
struct LinkStack *next; // 結點的指標域
} LStack_t;
LStack_t *LStack_Create(void) // 建立一個空連結串列,空連結串列應該有一個頭結點,對連結串列進行初始化
{
// 1.建立一個頭結點即棧頂並對頭結點申請記憶體
LStack_t *Top = (LStack_t *)calloc(1, sizeof(LStack_t));
if (NULL == Top)
{
perror("Calloc memory for Top is Failed");
exit(-1);
}
// 2.對頭結點進行初始化,不儲存有效內容,因此資料域初始化為0
Top->next = NULL;
Top->data = 0;
// 3.把頭結點的地址返回即可
return Top;
}
建立新的結點,並對新結點進行初始化(資料域 + 指標域)
LStack_t *LStack_NewNode(DataType_t data)
{
// 1.建立一個新結點並對新結點申請記憶體
LStack_t *New = (LStack_t *)calloc(1, sizeof(LStack_t));
if (NULL == New)
{
perror("Calloc memory for NewNode is Failed");
return NULL;
}
// 2.對新結點的資料域和指標域進行初始化
New->data = data;
New->next = NULL;
return New;
}
功能函式:入棧。因為是鏈式棧,因此只能允許在頭部進行入棧及出棧
bool LStack_Push(LStack_t *Top, DataType_t data)
{
// 1.建立新的結點,並對新結點進行初始化
LStack_t *New = LStack_NewNode(data);
if (NULL == New)
{
printf("can not insert new node\n");
return false;
}
/* 此處考慮兩種情況,如果連結串列為空或者非空:
1.如果為空,即滿足Top->next==NULL;
2.如果為非空,Top->next!=NULL,用下述程式碼也能滿足;
綜上,可以不用if語句判斷是否為空連結串列。
*/
New->next = Top->next;
Top->next = New;
return true;
}
功能函式:出棧
bool LStack_Pop(LStack_t *Top)
{
// 對首節點的地址進行備份
LStack_t *PTop = Top->next;
if (NULL == PTop) // 判斷是否為空表 judge is this a empty list.
{
printf("This is a empty list.\n");
return false;
}
/* 此處考慮兩種情況,如果連結串列僅有一個元素或一個以上的元素:
1.如果僅有一個元素,即滿足PTop->next==NULL;
2.如果為非空,PTop->next!=NULL,用下述程式碼也能滿足;
綜上,可以不用if語句判斷是否為僅有一個元素。
*/
Top->next = PTop->next;
PTop->next = NULL;
free(PTop);
return true;
}
功能函式:連結串列整體釋放
bool LStack_Free(LStack_t *Top) // 實現鏈式棧的整體釋放
{
// 對首節點的地址進行備份
if (Top == NULL)
{
printf("The list doesn't exist.\n");
return false;
}
LStack_t *PTop;
while (Top)
{
PTop = Top;
Top = Top->next;
free(PTop);
}
return true;
}
功能函式:鏈式棧元素展示
void LStack_Print(LStack_t *Top)
{
LStack_t *PTop = Top; // 對連結串列的標頭檔案的地址進行備份
if (Top == NULL)
{
printf("The list doesn't exist.\n");
return;
}
printf("4\n");
while (PTop->next) // 判斷是否為空連結串列
{
// 把頭的直接後繼作為新的頭結點
PTop = PTop->next;
// 輸出頭結點的直接後繼的資料域
printf("data = %d ", PTop->data);
}
}
主函式:進行功能函式測試
int main(int argc, char const *argv[])
{
LStack_t *H = (LStack_t *)calloc(1, sizeof(LStack_t));
LStack_Push(H, 10);
LStack_Push(H, 20);
LStack_Push(H, 30);
LStack_Print(H);
printf("1\n"); // 測試插入功能函式
LStack_Pop(H);
LStack_Print(H);
printf("2\n"); // 測試刪除功能函式
LStack_Free(H);
return 0;
}