主頁 >  其他 > ??資料結構之堆疊(圖文版詳解)??

??資料結構之堆疊(圖文版詳解)??

2021-09-25 17:04:36 其他

目錄

一,寫在前面

二,堆疊的定義

1,堆疊的定義

2,進堆疊出堆疊變化形式

三,堆疊的抽象資料型別

四,堆疊順序存盤結構及實作

1,堆疊的順尋存盤結構

2,堆疊的順序存盤結構——進堆疊操作

3,堆疊的順序存盤結構——出堆疊操作

五,兩堆疊共享空間

六,堆疊的鏈式存盤結構及實作

1,堆疊的鏈式存盤結構

2,堆疊的鏈式存盤結構——進堆疊操作

3, 堆疊的鏈式存盤結構——出堆疊操作

七,全部代碼

1,順序堆疊

2,兩堆疊共享空間

3,鏈堆疊


一,寫在前面

不知道大家有投有玩過手槍,估計都投有,現在和平年代,上哪去玩這種危險的 真東西,就是仿真玩具也大都被限制了.我高中在軍訓時,也算是一次機會,幾個老兵和我們學生聊天,讓我們學習了下關于槍的知識,

在你準備用槍的時候,那基本到了不是你死就是我亡的時刻,突然手槍明明有子彈卻打不出來,這不是要命嗎?而左輪手槍就不存在這問題,這一顆不行,轉到下顆就可以 了,人總不會倒霉到六顆全是臭彈, 當然,后來子彈質量基本過關了,由于彈夾可以 8顆顆甚至20顆子彈,比左輪手槍的只能放6顆子彈要多,所以后來普及率更高的彈夾手槍,

二,堆疊的定義

1,堆疊的定義

在我們軟體應用 ,堆疊這種后進先出資料結構的應用是非常普遍的,比如你用瀏覽器上網時不管什么瀏覽器都有 個"后退"鍵,你點擊后可以接訪問順序的逆序加載瀏覽過的網頁,比如你本來看著新聞好好的,突然看到有個鏈接說,有個可以讓 你年薪100萬的作業,你毫不猶豫點擊它, 跳轉進去一看,這都是啥呀,具體內容我 也就不說了,騙人騙得一點水平都沒有 時你還想回去繼續看新聞 就可以點擊左 上角的后退 ,即使你從一個網頁開始 連續點了幾十個鏈接跳轉 你點"后退',頁面跳轉到前一步,

很多類似的軟體,比如 Word Photoshop 等檔案或影像編 軟體中 都有撤銷 )的操作,也是用堆疊這種方式來實作的,當然不同的軟體具體實作代會有很 大差異,不過原理其實都是一樣的,

堆疊( stack )是限定僅在表尾進行插入和洗掉操作的線性表

我們把允許插入和洗掉的一端稱為堆疊頂 top ,另一端稱為堆疊底 bottom,不含任何資料元素的堆疊稱為空堆疊,又稱為后進先出 (Last In Filrst Out) 的線性表,簡 LlFO 結構,

堆疊的插入操作,叫作進堆疊,也稱壓堆疊、類似子彈入彈夾,

堆疊的洗掉操作,叫作出堆疊,也有的叫作彈堆疊,如同彈夾中的子彈出夾,

2,進堆疊出堆疊變化形式

最先進堆疊的元素,是不是就只能是最后出堆疊呢?

舉例來說,如果我們現在是有3個整型數字元素 1,2.3以次進堆疊,會有哪些出堆疊次序呢?

第一種: 1,2,3進,再 3,2,1出,這是最簡單的最好理解的 一種,出堆疊次序為 321 ,

第二種: 1進, 1出, 2進,2出, 3進, 3出,也就是進一 就出一個,出 枝次序為 123 ,

第三種: 1進,2進, 2出, 1出, 3進,3出,出堆疊次序為 213,

第四種:1進,1出,2進,3進,3出,2出,出堆疊次序為132,

第五種:1進,2進,2出,3進,3出,1出,出堆疊次序為231,

從這個簡單的例子就能看出,只是3個元素,就有5種可能的出堆疊次序,如果元素數量多,其實出堆疊的變化將會更多的,這個知識點一定要弄明白, 從這個簡單的例子就能看出,只是3個元素,就有5種可能的出堆疊次序,如果元素數量多,其實出堆疊的變化將會更多的.這個知識點一定要弄明白,

三,堆疊的抽象資料型別

對于堆疊來講,理論上線性表的操作特性它都具備,可由于它的特殊性,所以針對它在操作上會有些變化,特別是插入和洗掉操作,我們改名為 push和 pop,英文直譯的話是壓和彈,更容易理解,你就把它當成是彈夾的子彈壓入和彈出就好記憶了,我們一般叫進堆疊和出堆疊, 對于堆疊來講,理論上線性表的操作特性它都具備,可由于它的特殊性,所以針對它在操作上會有些變化.特別是插入和洗掉操作,我們改名為推和POP,英文直譯的話是壓和彈,更容易理解,你就把它當成是彈夾的子彈壓入和彈出就好記憶了,我們一般叫進堆疊和出堆疊,

ADT 堆疊(stack)
Data

  同線性表,元素具有相同的型別,相鄰元素具有前驅和后繼關系,
operation

InitStack(*S):初始化操作,建立一個空堆疊S.
DestoryStack (*S):若堆疊存在,則銷毀它,
ClearStack(*s):將堆疊清空,
StackEmpty (s):若堆疊為空,回傳true,否則回傳false,
GetTop (s, *e):若堆疊存在且非空,用e回傳S的堆疊頂元素,
Push(*S,e):若堆疊S存在,插入新元素e到堆疊s中并威為堆疊頂元素,
Pop (*s,*e):洗掉堆疊S中堆疊頂元素,并用e回傳其值,
StackLength(S):回傳堆疊s的元素個數,

endADT


四,堆疊順序存盤結構及實作

1,堆疊的順尋存盤結構

既然堆疊是線性表的特例,那么堆疊的順序存盤其實也是線性表順序存盤的簡化,我們簡稱為順序堆疊,線性表是用陣列來實作的,想想看,對于堆疊這種只能一頭插入洗掉的線性表來說,用陣列哪一端來作為堆疊頂和堆疊底比較好?
對,沒錯,下標為0的一端作為堆疊底比較好,因為首元素都存在堆疊底,變化最小,所以讓它作堆疊底,
我們定義一個 top變數來指示堆疊頂元素在陣列中的位置,這 top就如同中學物理學過的游標卡尺的游標,如圖,它可以來回移動,意味著堆疊頂的 top可以變大變小,但無論如何游標不能超出尺的長度,同理,若存盤堆疊的長度為StackSize,則堆疊頂位置top 必須小于 StackSize,當堆疊存在一個元素時,top等于0,因此通常把空堆疊的判定條件定為 top等于一1,

堆疊的結構定義

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存盤空間初始分配量 */
typedef int SElemType; /* SElemType型別根據實際情況而定,這里假設為int */

/* 順序堆疊結構 */
typedef struct
{
        SElemType data[MAXSIZE];
        int top; /* 用于堆疊頂指標 */
}SqStack;

若現在有一個堆疊,StackSize是5,則堆疊普通情況、空堆疊和堆疊滿的情況示意圖如圖 若現在有一個堆疊,StackSize是5,則堆疊普通情況、空堆疊和堆疊滿的情況示意圖如圖

2,堆疊的順序存盤結構——進堆疊操作

/* 插入元素e為新的堆疊頂元素 */
Status Push(SqStack *S,SElemType e)
{
        if(S->top == MAXSIZE -1) /* 堆疊滿 */
        {
                return ERROR;
        }
        S->top++;				/* 堆疊頂指標增加一 */
        S->data[S->top]=e;  /* 將新插入元素賦值給堆疊頂空間 */
        return OK;
}

3,堆疊的順序存盤結構——出堆疊操作

/* 若堆疊不空,則洗掉S的堆疊頂元素,用e回傳其值,并回傳OK;否則回傳ERROR */
Status Pop(SqStack *S,SElemType *e)
{ 
        if(S->top==-1)
                return ERROR;
        *e=S->data[S->top];	/* 將要洗掉的堆疊頂元素賦值給e */
        S->top--;				/* 堆疊頂指標減一 */
        return OK;
}

兩者沒有涉及到任何回圈陳述句,因此時間復雜度均是0(1),

五,兩堆疊共享空間

其實堆疊的順序存盤還是很方便的,因為它只準堆疊頂進出元素,所以不存在線性表插入和洗掉時需要移動元素的問題,不過它有一個很大的缺陷,就是必須事先確定陣列存盤空間大小,萬一不夠用了,就需要編程手段來擴展陣列的容量,非常麻煩,對于一個堆疊,我們也只能盡量考慮周全,設計出合適大小的陣列來處理,但對于兩個相同型別的堆疊,我們卻可以做到最大限度地利用其事先開辟的存盤空間來進行操作, 其實堆疊的順序存盤還是很方便的,因為它只準堆疊頂進出元素,所以不存在線性表插入和洗掉時需要移動元素的問題.不過它有一個很大的缺陷,就是必須事先確定陣列存盤空間大小,萬一不夠用了,就需要編程手段來擴展陣列的容量,非常麻煩.對于一個堆疊,我們也只能盡量考慮周全,設計出合適大小的陣列來處理,但對于兩個相同型別的堆疊,我們卻可以做到最大限度地利用其事先開辟的存盤空間來進行操作,

我們的做法如圖,陣列有兩個端點,兩個堆疊有兩個堆疊底,讓一個堆疊的堆疊底為陣列的始端,即下標為0處,另一個堆疊為堆疊的末端,即下標為陣列長度n-1處,這樣,兩個堆疊如果增加元素,就是兩端點向中間延伸, 我們的做法如圖,陣列有兩個端點,兩個堆疊有兩個堆疊底,讓一個堆疊的堆疊底為陣列的始端,即下標為0處,另一個堆疊為堆疊的末端,即下標為陣列長度n-1處.這樣,兩個堆疊如果增加元素,就是兩端點向中間延伸,

其實關鍵思路是:它們是在陣列的兩端,向中間靠攏,top1和 top2是堆疊1和堆疊2的堆疊頂指標,可以想象,只要它們倆不見面,兩個堆疊就可以一直使用,

從這里也就可以分析出來,堆疊1為空時,就是 top1等于-1時;而當top2等于n時,即是堆疊2為空時,那什么時候堆疊滿呢?

想想極端的情況,若堆疊2是空堆疊,堆疊1的 top1等于n-1時,就是堆疊1滿了,反之,當堆疊1為空堆疊時,top2等于0時,為堆疊2滿,但更多的情況,其實就是我剛才說的,兩個堆疊見面之時,也就是兩個指標之間相差1時,即 top1 + 1 == top2為堆疊滿,

兩堆疊共享空間的結構的代碼如下: 兩堆疊共享空間的結構的代碼如下:

/* 兩堆疊共享空間結構 */
typedef struct 
{
        SElemType data[MAXSIZE];
        int top1;	/* 堆疊1堆疊頂指標 */
        int top2;	/* 堆疊2堆疊頂指標 */
}SqDoubleStack;

對于兩堆疊共享空間的push方法,我們除了要插入元素值引數外,還需要有一個判斷是堆疊1還是堆疊2的堆疊號引數stackNumber,插入元素的代碼如下:

/* 插入元素e為新的堆疊頂元素 */
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
        if (S->top1+1==S->top2)	/* 堆疊已滿,不能再push新元素了 */
                return ERROR;	
        if (stackNumber==1)			/* 堆疊1有元素進堆疊 */
                S->data[++S->top1]=e; /* 若是堆疊1則先top1+1后給陣列元素賦值, */
        else if (stackNumber==2)	/* 堆疊2有元素進堆疊 */
                S->data[--S->top2]=e; /* 若是堆疊2則先top2-1后給陣列元素賦值, */
        return OK;
}

因為在開始已經判斷了是否有堆疊滿的情況,所以后面的 top1+1或top2-1是不擔心溢位問題的,

對于兩堆疊共享空間的pop方法,引數就只是判斷堆疊1堆疊2的引數stackNumber,代碼如下:

/* 若堆疊不空,則洗掉S的堆疊頂元素,用e回傳其值,并回傳OK;否則回傳ERROR */
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{ 
        if (stackNumber==1) 
        {
                if (S->top1==-1) 
                        return ERROR; /* 說明堆疊1已經是空堆疊,溢位 */
                *e=S->data[S->top1--]; /* 將堆疊1的堆疊頂元素出堆疊 */
        }
        else if (stackNumber==2)
        { 
                if (S->top2==MAXSIZE) 
                        return ERROR; /* 說明堆疊2已經是空堆疊,溢位 */
                *e=S->data[S->top2++]; /* 將堆疊2的堆疊頂元素出堆疊 */
        }
        return OK;
}

事實上,使用這樣的資料結構,通常都是當兩個堆疊的空間需求有相反關系時,也就是一個堆疊增長時另一個堆疊在縮短的情況,就像買賣股票一樣,你買入時,一定是有一個你不知道的人在做賣出操作,有人賺錢,就一定是有人賠錢,這樣使用兩堆疊共享空間存盤方法才有比較大的意義,否則兩個堆疊都在不停地增長,那很快就會因堆疊滿而溢位了,

六,堆疊的鏈式存盤結構及實作

1,堆疊的鏈式存盤結構

講完了堆疊的順序存盤結構,我們現在來看看堆疊的鏈式存盤結構,簡稱為鏈堆疊,想想看,堆疊只是堆疊頂來做插入和洗掉操作,堆疊頂放在鏈表的頭部還是尾部呢?由于單鏈表有頭指標,而堆疊頂指標也是必須的,那干嗎不讓它倆合二為一呢,所以比較好的辦法是把堆疊頂放在單鏈表的頭部(如圖所示),另外,都已經有了堆疊頂在頭部了,單鏈表中比較常用的頭結點也就失去了意義,通常對于鏈堆疊來說,是不需要頭結點的,

對于鏈堆疊來說,基本不存在堆疊滿的情況,除非記憶體已經沒有可以使用的空間,如果真的發生,那此時的計算機作業系統已經面臨死機崩潰的情況,而不是這個鏈堆疊是否溢位的問題,
但對于空堆疊來說,鏈表原定義是頭指標指向空,那么鏈堆疊的空其實就是 top=NULL的時候, 但對于空堆疊來說,鏈表原定義是頭指標指向空,那么鏈堆疊的空其實就是top=空的時候,

代碼如下:

/* 鏈堆疊結構 */
typedef struct StackNode
{
        SElemType data;
        struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct
{
        LinkStackPtr top;
        int count;
}LinkStack;

2,堆疊的鏈式存盤結構——進堆疊操作

對于鏈堆疊的進堆疊push操作,假設元素值為e的新結點是s,top為堆疊頂指標,示意圖如圖4所示代碼如下,

/* 插入元素e為新的堆疊頂元素 */
Status Push(LinkStack *S,SElemType e)
{
        LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
        s->data=e; 
        s->next=S->top;	/* 把當前的堆疊頂元素賦值給新結點的直接后繼,見圖中① */
        S->top=s;         /* 將新的結點s賦值給堆疊頂指標,見圖中② */
        S->count++;
        return OK;
}

3, 堆疊的鏈式存盤結構——出堆疊操作

至于鏈堆疊的出堆疊pop操作,也是很簡單的三句操作,假設變數p用來存盤要洗掉的堆疊頂結點,將堆疊頂指標下移一位,最后釋放p即可,如圖所示,


/* 若堆疊不空,則洗掉S的堆疊頂元素,用e回傳其值,并回傳OK;否則回傳ERROR */
Status Pop(LinkStack *S,SElemType *e)
{ 
        LinkStackPtr p;
        if(StackEmpty(*S))
                return ERROR;
        *e=S->top->data;
        p=S->top;					/* 將堆疊頂結點賦值給p,見圖中③ */
        S->top=S->top->next;    /* 使得堆疊頂指標下移一位,指向后一結點,見圖中④ */
        free(p);                    /* 釋放結點p */        
        S->count--;
        return OK;
}

七,全部代碼

1,順序堆疊

#include "stdio.h"    
#include "stdlib.h"   

#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存盤空間初始分配量 */

typedef int Status; 
typedef int SElemType; /* SElemType型別根據實際情況而定,這里假設為int */

/* 順序堆疊結構 */
typedef struct
{
        SElemType data[MAXSIZE];
        int top; /* 用于堆疊頂指標 */
}SqStack;

Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

/*  構造一個空堆疊S */
Status InitStack(SqStack *S)
{ 
        /* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
        S->top=-1;
        return OK;
}

/* 把S置為空堆疊 */
Status ClearStack(SqStack *S)
{ 
        S->top=-1;
        return OK;
}

/* 若堆疊S為空堆疊,則回傳TRUE,否則回傳FALSE */
Status StackEmpty(SqStack S)
{ 
        if (S.top==-1)
                return TRUE;
        else
                return FALSE;
}

/* 回傳S的元素個數,即堆疊的長度 */
int StackLength(SqStack S)
{ 
        return S.top+1;
}

/* 若堆疊不空,則用e回傳S的堆疊頂元素,并回傳OK;否則回傳ERROR */
Status GetTop(SqStack S,SElemType *e)
{
        if (S.top==-1)
                return ERROR;
        else
                *e=S.data[S.top];
        return OK;
}

/* 插入元素e為新的堆疊頂元素 */
Status Push(SqStack *S,SElemType e)
{
        if(S->top == MAXSIZE -1) /* 堆疊滿 */
        {
                return ERROR;
        }
        S->top++;				/* 堆疊頂指標增加一 */
        S->data[S->top]=e;  /* 將新插入元素賦值給堆疊頂空間 */
        return OK;
}

/* 若堆疊不空,則洗掉S的堆疊頂元素,用e回傳其值,并回傳OK;否則回傳ERROR */
Status Pop(SqStack *S,SElemType *e)
{ 
        if(S->top==-1)
                return ERROR;
        *e=S->data[S->top];	/* 將要洗掉的堆疊頂元素賦值給e */
        S->top--;				/* 堆疊頂指標減一 */
        return OK;
}

/* 從堆疊底到堆疊頂依次對堆疊中每個元素顯示 */
Status StackTraverse(SqStack S)
{
        int i;
        i=0;
        while(i<=S.top)
        {
                visit(S.data[i++]);
        }
        printf("\n");
        return OK;
}

int main()
{
        int j;
        SqStack s;
        int e;
        if(InitStack(&s)==OK)
                for(j=1;j<=10;j++)
                        Push(&s,j);
        printf("堆疊中元素依次為:");
        StackTraverse(s);
        Pop(&s,&e);
        printf("彈出的堆疊頂元素 e=%d\n",e);
        printf("堆疊空否:%d(1:空 0:否)\n",StackEmpty(s));
        GetTop(s,&e);
        printf("堆疊頂元素 e=%d 堆疊的長度為%d\n",e,StackLength(s));
        ClearStack(&s);
        printf("清空堆疊后,堆疊空否:%d(1:空 0:否)\n",StackEmpty(s));
        
        return 0;
}

2,兩堆疊共享空間

#include "stdio.h"    
#include "stdlib.h"   

#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存盤空間初始分配量 */

typedef int Status; 

typedef int SElemType; /* SElemType型別根據實際情況而定,這里假設為int */


/* 兩堆疊共享空間結構 */
typedef struct 
{
        SElemType data[MAXSIZE];
        int top1;	/* 堆疊1堆疊頂指標 */
        int top2;	/* 堆疊2堆疊頂指標 */
}SqDoubleStack;


Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

/*  構造一個空堆疊S */
Status InitStack(SqDoubleStack *S)
{ 
        S->top1=-1;
        S->top2=MAXSIZE;
        return OK;
}

/* 把S置為空堆疊 */
Status ClearStack(SqDoubleStack *S)
{ 
        S->top1=-1;
        S->top2=MAXSIZE;
        return OK;
}

/* 若堆疊S為空堆疊,則回傳TRUE,否則回傳FALSE */
Status StackEmpty(SqDoubleStack S)
{ 
        if (S.top1==-1 && S.top2==MAXSIZE)
                return TRUE;
        else
                return FALSE;
}

/* 回傳S的元素個數,即堆疊的長度 */
int StackLength(SqDoubleStack S)
{ 
        return (S.top1+1)+(MAXSIZE-S.top2);
}

/* 插入元素e為新的堆疊頂元素 */
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
        if (S->top1+1==S->top2)	/* 堆疊已滿,不能再push新元素了 */
                return ERROR;	
        if (stackNumber==1)			/* 堆疊1有元素進堆疊 */
                S->data[++S->top1]=e; /* 若是堆疊1則先top1+1后給陣列元素賦值, */
        else if (stackNumber==2)	/* 堆疊2有元素進堆疊 */
                S->data[--S->top2]=e; /* 若是堆疊2則先top2-1后給陣列元素賦值, */
        return OK;
}

/* 若堆疊不空,則洗掉S的堆疊頂元素,用e回傳其值,并回傳OK;否則回傳ERROR */
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{ 
        if (stackNumber==1) 
        {
                if (S->top1==-1) 
                        return ERROR; /* 說明堆疊1已經是空堆疊,溢位 */
                *e=S->data[S->top1--]; /* 將堆疊1的堆疊頂元素出堆疊 */
        }
        else if (stackNumber==2)
        { 
                if (S->top2==MAXSIZE) 
                        return ERROR; /* 說明堆疊2已經是空堆疊,溢位 */
                *e=S->data[S->top2++]; /* 將堆疊2的堆疊頂元素出堆疊 */
        }
        return OK;
}

Status StackTraverse(SqDoubleStack S)
{
        int i;
        i=0;
        while(i<=S.top1)
        {
                visit(S.data[i++]);
        }
        i=S.top2;
        while(i<MAXSIZE)
        {
                visit(S.data[i++]);
        }
        printf("\n");
        return OK;
}

int main()
{
        int j;
        SqDoubleStack s;
        int e;
        if(InitStack(&s)==OK)
        {
                for(j=1;j<=5;j++)
                        Push(&s,j,1);
                for(j=MAXSIZE;j>=MAXSIZE-2;j--)
                        Push(&s,j,2);
        }

        printf("堆疊中元素依次為:");
        StackTraverse(s);

        printf("當前堆疊中元素有:%d \n",StackLength(s));

        Pop(&s,&e,2);
        printf("彈出的堆疊頂元素 e=%d\n",e);
        printf("堆疊空否:%d(1:空 0:否)\n",StackEmpty(s));

        for(j=6;j<=MAXSIZE-2;j++)
                Push(&s,j,1);

        printf("堆疊中元素依次為:");
        StackTraverse(s);

        printf("堆疊滿否:%d(1:否 0:滿)\n",Push(&s,100,1));

        
        ClearStack(&s);
        printf("清空堆疊后,堆疊空否:%d(1:空 0:否)\n",StackEmpty(s));
        
        return 0;
}

3,鏈堆疊

#include "stdio.h"    
#include "stdlib.h"   

#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存盤空間初始分配量 */

typedef int Status; 
typedef int SElemType; /* SElemType型別根據實際情況而定,這里假設為int */


/* 鏈堆疊結構 */
typedef struct StackNode
{
        SElemType data;
        struct StackNode *next;
}StackNode,*LinkStackPtr;


typedef struct
{
        LinkStackPtr top;
        int count;
}LinkStack;

Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

/*  構造一個空堆疊S */
Status InitStack(LinkStack *S)
{ 
        S->top = (LinkStackPtr)malloc(sizeof(StackNode));
        if(!S->top)
                return ERROR;
        S->top=NULL;
        S->count=0;
        return OK;
}

/* 把S置為空堆疊 */
Status ClearStack(LinkStack *S)
{ 
        LinkStackPtr p,q;
        p=S->top;
        while(p)
        {  
                q=p;
                p=p->next;
                free(q);
        } 
        S->count=0;
        return OK;
}

/* 若堆疊S為空堆疊,則回傳TRUE,否則回傳FALSE */
Status StackEmpty(LinkStack S)
{ 
        if (S.count==0)
                return TRUE;
        else
                return FALSE;
}

/* 回傳S的元素個數,即堆疊的長度 */
int StackLength(LinkStack S)
{ 
        return S.count;
}

/* 若堆疊不空,則用e回傳S的堆疊頂元素,并回傳OK;否則回傳ERROR */
Status GetTop(LinkStack S,SElemType *e)
{
        if (S.top==NULL)
                return ERROR;
        else
                *e=S.top->data;
        return OK;
}

/* 插入元素e為新的堆疊頂元素 */
Status Push(LinkStack *S,SElemType e)
{
        LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
        s->data=e; 
        s->next=S->top;	/* 把當前的堆疊頂元素賦值給新結點的直接后繼,見圖中① */
        S->top=s;         /* 將新的結點s賦值給堆疊頂指標,見圖中② */
        S->count++;
        return OK;
}

/* 若堆疊不空,則洗掉S的堆疊頂元素,用e回傳其值,并回傳OK;否則回傳ERROR */
Status Pop(LinkStack *S,SElemType *e)
{ 
        LinkStackPtr p;
        if(StackEmpty(*S))
                return ERROR;
        *e=S->top->data;
        p=S->top;					/* 將堆疊頂結點賦值給p,見圖中③ */
        S->top=S->top->next;    /* 使得堆疊頂指標下移一位,指向后一結點,見圖中④ */
        free(p);                    /* 釋放結點p */        
        S->count--;
        return OK;
}

Status StackTraverse(LinkStack S)
{
        LinkStackPtr p;
        p=S.top;
        while(p)
        {
                 visit(p->data);
                 p=p->next;
        }
        printf("\n");
        return OK;
}

int main()
{
        int j;
        LinkStack s;
        int e;
        if(InitStack(&s)==OK)
                for(j=1;j<=10;j++)
                        Push(&s,j);
        printf("堆疊中元素依次為:");
        StackTraverse(s);
        Pop(&s,&e);
        printf("彈出的堆疊頂元素 e=%d\n",e);
        printf("堆疊空否:%d(1:空 0:否)\n",StackEmpty(s));
        GetTop(s,&e);
        printf("堆疊頂元素 e=%d 堆疊的長度為%d\n",e,StackLength(s));
        ClearStack(&s);
        printf("清空堆疊后,堆疊空否:%d(1:空 0:否)\n",StackEmpty(s));
        return 0;
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302781.html

標籤:其他

上一篇:自定義型別:結構體,列舉,聯合(C語言)

下一篇:計算機組成原理筆記 (1):計算機組成概述

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more