對棧的實現(順序棧和鏈式棧)C語言

棧的實現

兩種方法實現:

  • 順序棧
    :基於靜態順序表
  • 鏈式棧
    :基於鏈表

    順序棧

函數的結構體和聲明

基於順序表的棧,也就是用數組的增刪查改
我們看結構體和聲明
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;
}

如有錯誤,還望指正。謝謝。

發佈了74 篇原創文章 · 獲贊 35 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章