鏈式棧介面設計(C語言)

Rice_rice發表於2024-04-25

鏈式棧介面設計

/**

* @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;
}

相關文章