鏈式棧,顧名思義,就是規定一個只能頭插頭刪或者尾插尾刪的鏈表,來實現棧結構先進先出原則
在這裏我們選用頭插和頭刪的方法,因爲尾插和尾刪都需要遍歷鏈表,時間複雜度較高。
不多比比,直接通過代碼演示
- 結構體聲明
typedef char LinkListType;
typedef struct LinkListStack{
struct LinkListStack* next;//指針域,指向下一個節點的指針
LinkListType data;//數據域,用來存放數據
}LinkListStack;
- 具體函數聲明
//初始化棧
void LinkListStackInit(LinkListStack** head);
//入棧
void LinkListStackPush(LinkListStack** head,LinkListType value);
//出棧
void LinkListStackPop(LinkListStack** head);
//銷燬棧
void DestroyNode(LinkListStack* node);
//創建新節點
LinkListStack* CreateNode(LinkListType value);
//取棧頂元素
int LinkListStackGetTop(LinkListStack* head,LinkListType* value);
初始化和銷燬
void LinkListStackInit(LinkListStack** head)
{
if(head==NULL){
//非法輸入
return;
}
*head=NULL;
}
//封裝free函數,實現單個節點的銷燬,如果想一次性銷燬整個棧,需要遍歷鏈表,依次釋放每個節點空間纔可以
void DestroyNode(LinkListStack* node)
{
free(node);
}
入棧和出棧
//因爲鏈表中的節點都是一塊獨立的內存空間,所以在進行創建棧或者插入操作時,就需要開闢新的內存空間
//並分配給每個節點,因爲堆上開闢的空間是不連續的,所以節點與節點之間需要一個next指針來連接起來
LinkListStack* CreateNode(LinkListType value)
{
LinkListStack* newNode = (LinkListStack*)malloc(sizeof(LinkListStack));
newNode->next = NULL;
newNode->data = value;
return newNode;
}
//入棧
//頭插時間複雜度爲O(1),推薦
void LinkListStackPush(LinkListStack** head,LinkListType value)
{
if(head == NULL)
{
//非法輸入
return;
}
if(*head==NULL)
{
//空棧
*head = CreateNode(value);
return;
}
LinkListStack* cur = CreateNode(value);
cur->next = *head;
*head = cur;
}
//出棧
//頭刪時間複雜度爲O(1),推薦
void LinkListStackPop(LinkListStack** head)
{
if(head==NULL)
{
//非法輸入
return;
}
if(*head==NULL)
{
//空棧
return;
}
LinkListStack* cur = *head;
*head=(*head)->next;
DestroyNode(cur);
}
取出棧頂元素同樣是需要輸出型參數
int LinkListStackGetTop(LinkListStack* head,LinkListType* value)
{
if(head==NULL){
//空鏈表
return 0;
}
*value = head->data;
return 1;
}