棧的實現
兩種方法實現:
- 順序棧
:基於靜態順序表 鏈式棧
:基於鏈表順序棧
函數的結構體和聲明
基於順序表的棧,也就是用數組的增刪查改
我們看結構體和聲明
typedef char SeqType;
typedef struct SeqStack{
size_t size;
SeqType data[MAXREPOSITORY];
}SeqStack;
// 初始化。
void SeqStackInit(SeqStack *seq);
// 入棧。
void SeqStackPushStack(SeqStack *seq, SeqType value);
// 出棧。
void SeqStackPopStack(SeqStack *seq);
// 取棧頂元素。
int SeqStackFindTop(SeqStack *seq, SeqType *value);
// 銷燬。
void SeqStackDestory(SeqStack *seq);
函數的定義
#include "SeqStack.h"
// 函數在初始化時候已經爲其開闢空間所以這裏是要初始化就行
// 初始化。
void SeqStackInit(SeqStack *seq)
{
if (seq == NULL)
{
// 非法輸入。
return;
}
seq->size = 0;
}
// 這裏的入棧就和順序表的尾插一樣,注意就是需要判斷是否棧滿
// 入棧。
void SeqStackPushStack(SeqStack *seq, SeqType value)
{
if (seq == NULL)
{
return;
}
if (seq->size > MAXREPOSITORY)
{
return;
}
seq->data[seq->size] = value;
++seq->size;
}
// 打印棧。
void PrintSeqStack(SeqStack *seq)
{
if (seq == NULL)
{
return;
}
printf("棧底->");
size_t i = 0;
for (; i<seq->size; ++i)
{
printf("[%c]->",seq->data[i]);
}
printf("棧頂\n");
}
// 出棧需要注意棧是否爲空
// 出棧。
void SeqStackPopStack(SeqStack *seq)
{
if (seq == NULL)
{
// 非法輸入。
return;
}
if (seq->size == 0)
{
// 空順序表。
return;
}
--seq->size;
}
// 取棧頂元素。
int SeqStackFindTop(SeqStack *seq, SeqType *value)
{
if (seq == NULL)
{
return 0;
}
if (seq->size == 0)
{
printf("棧爲空棧。");
// 空棧。
return 0;
}
*value = seq->data[seq->size-1];
return 1;
}
// 銷燬。
void SeqStackDestory(SeqStack *seq)
{
if (seq == NULL)
{
return;
}
seq->size = 0;
}
以下是代碼的單元測試
/////////////////////
//測試代碼
/////////////////////
// 初始化
void TestSeqStackInit()
{
PRINTSEQSTACKNAME;
SeqStack seq;
SeqStackInit(&seq);
}
// 入棧。
void TestSeqStackPushStack()
{
PRINTSEQSTACKNAME;
SeqStack seq;
SeqStackInit(&seq);
SeqStackPushStack(&seq, 'a');
SeqStackPushStack(&seq, 'b');
SeqStackPushStack(&seq, 'c');
SeqStackPushStack(&seq, 'd');
PrintSeqStack(&seq);
}
// 出棧。
void TestSeqStackPopStack()
{
PRINTSEQSTACKNAME;
SeqStack seq;
SeqStackInit(&seq);
SeqStackPushStack(&seq, 'a');
SeqStackPushStack(&seq, 'b');
SeqStackPushStack(&seq, 'c');
SeqStackPushStack(&seq, 'd');
PrintSeqStack(&seq);
SeqStackPopStack(&seq);
PrintSeqStack(&seq);
SeqStackPopStack(&seq);
SeqStackPopStack(&seq);
SeqStackPopStack(&seq);
PrintSeqStack(&seq);
SeqStackPopStack(&seq);
PrintSeqStack(&seq);
}
// 取棧頂元素。
void TestSeqStackFindTop()
{
PRINTSEQSTACKNAME;
SeqStack seq;
SeqStackInit(&seq);
SeqStackPushStack(&seq, 'a');
SeqStackPushStack(&seq, 'b');
SeqStackPushStack(&seq, 'c');
SeqStackPushStack(&seq, 'd');
PrintSeqStack(&seq);
SeqType ret = SeqStackFindTop(&seq);
printf("except d actual %c\n",ret);
}
int main()
{
TestSeqStackInit();
TestSeqStackPushStack();
TestSeqStackPopStack();
TestSeqStackFindTop();
return 0;
}
鏈式棧
函數的結構體和聲明
函數結構體和鏈表節點的實現相同。
typedef char LinkType;
typedef struct LinkNode{
LinkType data;
struct LinkNode *next;
}LinkNode;
// 我採用的是帶有單鏈表實現的棧
// 初始化。帶頭不帶環單鏈表。
void LinkStackInit(LinkNode *head);
// 入棧。
void LinkStackPushStack(LinkNode *head, LinkType value);
// 出棧。
void LinkStackPopStack(LinkNode *head);
// 取棧頂元素。
int LinkStackFindTop(LinkNode *head, LinkType *value);
// 銷燬。
void LinkStackDestory(LinkNode *head);
函數的定義
#include"LinkStack.h"
// 初始化。帶頭不帶環單鏈表。
void LinkStackInit(LinkNode *head)
{
if (head == NULL)
{
return;
}
head->next = NULL;
}
// 創建節點。
LinkNode *CreatNode(LinkType value)
{
LinkNode *new_node = (LinkNode*)malloc(sizeof(LinkNode));
if (new_node == NULL)
{
// 申請內存失敗。
return NULL;
}
new_node->data = value;
new_node->next = NULL;
return new_node;
}
// 這裏可以看出直接在head後面插節點
// 入棧。
void LinkStackPushStack(LinkNode *head, LinkType value)
{
if (head == NULL)
{
return;
}
LinkNode *new_node = CreatNode(value);
if (new_node == NULL)
{
printf("內存申請失敗。");
// 返回值爲NULL。
return;
}
LinkNode *next = head->next;
head->next = new_node;
new_node->next = next;
}
// 出棧。
void LinkStackPopStack(LinkNode *head)
{
if (head == NULL)
{
return;
}
if (head->next == NULL)
{
// 空棧。
return;
}
LinkNode *delete = head->next;
head->next = delete->next;
free(delete);
}
// 這裏要注意帶頭單鏈表取棧頂元素,是head的next節點。
// 取棧頂元素。
int LinkStackFindTop(LinkNode *head, LinkType *value)
{
if (head == NULL)
{
return -1;
}
if (head->next == NULL)
{
return 0;
}
*value = head->next->data;
return 1;
}
// 銷燬要遍歷一個一個節點的釋放。
// 銷燬。
void LinkStackDestory(LinkNode *head)
{
if (head == NULL)
{
return;
}
LinkNode *cur = head->next;
while (cur != NULL)
{
LinkNode *next = cur->next;
head->next = next;
free(cur);
cur = next;
}
}
鏈式棧的單元測試
/////////////
//測試代碼
/////////////
#define LINKSTACKNAME printf("\n=========%s========\n",__FUNCTION__)
// 打印。
void PrintLinkStack(LinkNode *head)
{
if (head == NULL)
{
return;
}
printf("(TOP)head->");
LinkNode *cur = head->next;
while (cur != NULL)
{
printf("[%c]->",cur->data);
cur = cur->next;
}
printf("BOTTOM\n");
}
// 初始化。
void TestLinkStackInit()
{
LINKSTACKNAME;
LinkNode head;
LinkStackInit(&head);
}
// 入棧。
void TestLinkStackPushStack()
{
LINKSTACKNAME;
LinkNode head;
LinkStackInit(&head);
LinkStackPushStack(&head,'a');
LinkStackPushStack(&head,'b');
LinkStackPushStack(&head,'c');
LinkStackPushStack(&head,'d');
PrintLinkStack(&head);
}
// 出棧。
void TestLinkStackPopStack()
{
LINKSTACKNAME;
LinkNode head;
LinkStackInit(&head);
LinkStackPushStack(&head,'a');
LinkStackPushStack(&head,'b');
LinkStackPushStack(&head,'c');
LinkStackPushStack(&head,'d');
PrintLinkStack(&head);
LinkStackPopStack(&head);
PrintLinkStack(&head);
LinkStackPopStack(&head);
LinkStackPopStack(&head);
PrintLinkStack(&head);
LinkStackPopStack(&head);
PrintLinkStack(&head);
LinkStackPopStack(&head);
PrintLinkStack(&head);
}
// 銷燬。
void TestLinkStackDestory()
{
LINKSTACKNAME;
LinkNode head;
LinkStackInit(&head);
LinkStackPushStack(&head,'a');
LinkStackPushStack(&head,'b');
LinkStackPushStack(&head,'c');
LinkStackPushStack(&head,'d');
PrintLinkStack(&head);
LinkStackDestory(&head);
PrintLinkStack(&head);
}
int main()
{
TestLinkStackInit();
TestLinkStackPushStack();
TestLinkStackPopStack();
TestLinkStackDestory();
return 0;
}
如有錯誤,還望指正。謝謝。