數據結構之 棧與隊列(一)

什麼是棧

棧是一種用來存儲,邏輯關係爲“一對一”的線性存儲結構,棧的存取遵循“先進後出”原則。

棧有以下兩種特性:

  • 棧只能從表的一端存取數據,另一端是封閉的
  • 棧中,無論是存數據還是取數據,都必須遵循"先進後出"的原則,即最先進棧的元素最後出棧。拿圖 1 的棧來說,從圖中數據的存儲狀態可判斷出,元素 1 是最先進的棧。因此,當需要從棧中取出元素 1 時,根據"先進後出"的原則,需提前將元素 3 和元素 2 從棧中取出,然後才能成功取出元素 1。

棧頂與棧底:

  • 棧的開口被稱爲棧頂,封口端被稱爲棧底。
  • 棧頂元素是距離棧頂最近的元素
  • 棧底元素是距離棧底最近的元素

進棧與出棧:

  • 向棧中添加元素,被稱爲“進棧”(入棧或壓棧)
  • 向棧中提取出指定元素,被稱爲“出棧”(彈棧)

棧的具體實現:

  • 順序棧:採用順序存儲的結構模擬存取數據的特點
  • 鏈棧:採用鏈式結構模擬棧

順序棧的代碼實現:

入棧:

//進棧,p爲數組,top值爲當前棧的棧頂位置
int push(int* p,int top,int elem){
    ++top;
    p[top]=elem;
    return top;
}

在最開始的時候,棧是空的,所以指針元素top = -1;然後向棧中添加元素1,以數組下標0端表示棧底,1被存儲在a[1]處,top值+1。

出棧:

//出棧
int pop(int * p,int top){
    if (top==-1) {
        printf("空棧");
        return -1;
    }
    printf("出棧元素:%d\n",p[top]);
    top--;
    return top;
}

對於元素出棧的實現,top值-1即可

全部代碼:

#include <stdio.h>
//進棧
int push(int* a,int top,int elem){
    a[++top]=elem;
    return top;
}
//出棧
int pop(int * p,int top){
    if (top==-1) {
        printf("空棧");
        return -1;
    }
    printf("出棧元素:%d\n",p[top]);
    top--;
    return top;
}
int main() {
    int a[100];
    int top=-1;
	int i=0;
    for(i=1;i<5;i++){
		top=push(a, top, i);
    }
	for(i=4;i>-1;i--){
        top=pop(a, top);
    }
    return 0;
}

鏈棧的基本操作

基本思想:

鏈棧的實現思路同順序棧類似,順序棧是將數順序表(數組)的一端作爲棧底,另一端爲棧頂;鏈棧也如此,通常我們將鏈表的頭部作爲棧頂,尾部作爲棧底。
圖片來源於網絡

將鏈表頭部作爲棧頂的一端,可以避免在實現數據 “入棧” 和 “出棧” 操作時做大量遍歷鏈表的耗時操作。但也正因爲此,所以入棧時,必須將數據從鏈表頭部插入,出棧時,也需要刪除鏈表頭部的首元素節點。
所以可以把鏈棧稱之爲:只能採用頭插法插入或刪除數據的鏈表

鏈棧入棧:

圖片來源於網絡

//鏈表中的節點結構
typedef struct lineStack{
    int data;
    struct lineStack * next;
}lineStack;
//stack爲鏈棧,a爲入棧的元素
lineStack* push(lineStack * stack,int a){
    //創建存儲新元素的節點
    lineStack * line=(lineStack*)malloc(sizeof(lineStack));
    line->data=a;
    //新節點與頭節點建立邏輯關係
    line->next=stack;
    //更新頭指針的指向
    stack=line;
    return stack;
}

鏈棧出棧:

若要讓棧中某元素出棧,則必須要該元素之前的所有元素都出棧,遵循“先進後出”原則。

代碼如下:

lineStack * pop(lineStack * stack){
    if (stack) {
        //定義一個指針指向棧頂節點
        lineStack * p=stack;
        //更新頭指針
        stack=stack->next;
        printf("出棧元素:%d ",p->data);
        if (stack) {
            printf("新棧頂元素:%d\n",stack->data);
        }else{
            printf("棧已空\n");
        }
        free(p);
    }else{
        printf("棧內沒有元素");
        return stack;
    }
    return stack;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章