之前用順序表實現了棧,今天用鏈表來模擬實現一個棧。之前也都說了,棧的最大特性就是先進後出,先入棧的元素後出棧。
下面這張圖,就是我畫的入棧出棧示意圖。
第二個是入棧。第三個是出棧,a,b元素是先入棧的,入棧是從頭節點的下一個元素開始入棧,出棧也是這裏,都是隻改變頭指針的下一個元素就行。由於是這樣的,所有鏈式棧實現起來比較簡單,不像順序棧那樣,需要大規模挪動數據。
好了,下面就開始寫代碼吧:
ListStack.h
#pragma once
//鏈表實現的棧(鏈式棧)
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
typedef char DataType;
typedef struct ListNode
{
DataType data;
struct ListNode* _next;
}ListNode;
//初始化
void ListStackInit(ListNode **l);
//銷燬
void ListStackDestroy(ListNode *l);
//入棧
void ListStackPush(ListNode *l,DataType data);
//出棧
void ListStackPop(ListNode *l);
//取棧頂元素
DataType ListStackTop(ListNode l);
LinkStack.c
#include "ListStack.h"
//初始化
void ListStackInit(ListNode **l)
{
//初始化頭節點
assert(l);
(*l) = (ListNode*)malloc(sizeof(ListNode));
(*l)->_next = NULL;
}
//創建一個結點
ListNode* CreateNode(DataType value)
{
ListNode *newnode = (ListNode*)malloc(sizeof(ListNode));
newnode->data = value;
newnode->_next = NULL;
return newnode;
}
//銷燬一個結點
void DestroyNode(ListNode *p)
{
assert(p);
free(p);
p = NULL;
}
//銷燬
void ListStackDestroy(ListNode *l)
{
assert(l);
if(l->_next == NULL)
return;
ListNode *tmp = l;
while(tmp != NULL)
{
ListNode *next = tmp->_next;
DestroyNode(tmp);
tmp = next;
}
l->_next = NULL;
}
//入棧
void ListStackPush(ListNode *l,DataType data)
{
//頭插
assert(l);
ListNode *newnode = CreateNode(data);
newnode->_next = l->_next;
l->_next = newnode;
}
//出棧
void ListStackPop(ListNode *l)
{
assert(l);
if(l->_next == NULL)
return;
ListNode *tmp = l->_next;
l->_next = tmp->_next;
DestroyNode(tmp);
}
//取棧頂元素
DataType ListStackTop(ListNode l)
{
assert(l._next);
return (l._next->data);
}
//打印棧
void PrintStack(ListNode l)
{
ListNode *tmp = (&l)->_next;
printf("[head] ");
while(tmp != NULL)
{
printf("[%c] ",tmp->data);
tmp = tmp->_next;
}
printf("\n");
}
測試代碼:
#define TESTHEAD printf("-------------------------------%s---------------------------------------\n",__FUNCTION__)
void testPush()
{
TESTHEAD;
ListNode *l = NULL;
ListStackInit(&l);
ListStackPush(l,'a');
ListStackPush(l,'b');
ListStackPush(l,'c');
ListStackPush(l,'d');
ListStackPush(l,'e');
PrintStack(*l);
}
void testPop()
{
TESTHEAD;
ListNode *l = NULL;
ListStackInit(&l);
ListStackPush(l,'a');
ListStackPush(l,'b');
ListStackPush(l,'c');
ListStackPush(l,'d');
ListStackPush(l,'e');
PrintStack(*l);
ListStackPop(l);
ListStackPop(l);
PrintStack(*l);
}
void testDestroy()
{
TESTHEAD;
ListNode *l = NULL;
ListStackInit(&l);
ListStackPush(l,'a');
ListStackPush(l,'b');
ListStackPush(l,'c');
ListStackPush(l,'d');
ListStackPush(l,'e');
PrintStack(*l);
ListStackDestroy(l);
PrintStack(*l);
}
void testTop()
{
TESTHEAD;
ListNode *l = NULL;
ListStackInit(&l);
ListStackPush(l,'a');
ListStackPush(l,'b');
ListStackPush(l,'c');
ListStackPush(l,'d');
ListStackPush(l,'e');
PrintStack(*l);
DataType ret = ListStackTop(*l);
printf("棧頂元素:%c \n",ret);
}
代碼測試結果: