1. 程式人生 > >23-棧的鏈式儲存結構和基本運算實現

23-棧的鏈式儲存結構和基本運算實現

1. 棧的鏈式儲存結構

  棧的鏈式儲存結構也稱為鏈棧,棧的鏈式儲存結構本質上還是以線性表的鏈式儲存來實現的,一般來說,連結串列有頭指標,棧也有棧頂指標,那麼可以把棧頂放在連結串列的頭部,用頭指標來表示棧頂指標,但是這裡我們不用頭結點儲存棧頂節點,而是讓頭結點的next指標指向棧頂節點。

這裡寫圖片描述
圖1-棧的鏈式儲存結構

棧的鏈式儲存結構定義如下所示:

//定義鏈棧的結點
typedef struct STACKNODE
{
    void *data;                 //資料域
    struct STACKNODE* next;     //next指標域
} StackNode;

//定義鏈棧結構
typedef struct LINKSTACK { struct STACKNODE top; //棧頂節點 int length; //鏈棧的節點個數 }LinkStack;



鏈棧的4要素:

  1. 對於鏈棧來說,基本不存在棧滿的情況

  2. 進棧操作,將包含e的節點插入到頭節點之後

  3. 出棧操作,取出頭節點之後節點的元素並刪除之

  4. 棧空條件為top = NULL,當鏈棧的棧頂節點top為NULL,說明鏈棧為空,沒有節點。

  對於鏈棧來說,基本不存在棧滿的情況,除非計算機已經沒有記憶體可用。但是鏈棧是有可能為空的,對於鏈棧為空的條件就是棧頂指標top = NULL。

2. 鏈式棧的基本運算實現

1.初始化棧initStack(&s)

  建立一個空棧s,然後將棧頂節點top置為NULL

這裡寫圖片描述
void InitStack(LiStack *&s)
{
    //給鏈棧s分配記憶體空間
    s=(LiStack *)malloc(sizeof(LiStack));
    //將next指標域置為NULL
    s->next=NULL;
}

2.銷燬棧ClearStack(&s)

  釋放棧s佔用的全部儲存空間,q指向下一個節點,p記錄要釋放的節點

這裡寫圖片描述
void DestroyStack(LiStack *&
s) { LiStack *p=s,*q=s->next; while (q!=NULL) { free(p); p=q; q=p->next; } free(p); }

3.判斷棧是否為空StackEmpty(s)

  棧S為空的條件是s->next==NULL,說明鏈棧中沒有資料節點。

bool StackEmpty(LiStack *s)
{
    return(s->next==NULL);
}

4.進棧Push(&s,e)

  將新資料節點e插入到頭節點之後

這裡寫圖片描述
void Push(LiStack *&s,ElemType e)
{
    LiStack *p;
    p=(LiStack *)malloc(sizeof(LiStack));
    p->data=e;
    p->next=s->next;
    s->next=p;
}

5 . 出棧Pop(&s,&e)

  在棧不為空的條件下,將頭節點後繼資料節點的資料域賦給e,然後將其刪除。

這裡寫圖片描述
bool Pop(LiStack *&s,ElemType &e)
{
    LiStack *p;
    //先判斷棧是否為空
    if (s->next==NULL)
        return false;
    //出棧操作
    p=s->next;
    e=p->data;
    s->next=p->next;
    free(p);
    return true;
}

6.取棧頂元素GetTop(s,e)

  在棧不為空的條件下,將頭節點後繼資料節點的資料域賦給e

這裡寫圖片描述
bool GetTop(LiStack *s,ElemType &e)
{   
    if (s->next==NULL)
        return false;
    //把棧頂節點賦給e
    e=s->next->data;
    return true;
    }