07.棧(一)棧的儲存結構及操作,07儲存結構操作

來源:互聯網
上載者:User

07.棧(一)棧的儲存結構及操作,07儲存結構操作
一、棧1.棧(stack):是限定僅在表尾進行插入和刪除操作的線性表。其中,允許插入和刪除的一端被稱為棧頂(top),另一端被稱為棧底(bottom),不含任何資料元素的棧被稱為空白棧。棧又被稱為後進先出(Last In First Out)的線性表,簡稱LIFO結構。    棧的插入操作為進棧,棧的刪除操作為出棧。2.棧的抽象資料類型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.棧的順序儲存結構及實現(複雜度均為O(1))(1)棧順序結構定義#define OK 1#define ERROR 0typedef int SElemType;    //SElemType類型根據實際情況而定,這裡假設為inttypedef struct{    SElemType data[MAXSIZE];    //棧儲存空間大小MAXSIZE    int top;    //用於棧頂指標}SqStack;(2)進棧操作(從棧頂插入一個元素)演算法思路:a.判定是否棧滿;b.棧頂加1;c.將元素插入到實現:插入元素e為新的棧頂元素

Status Push(SqStack *S,SElemType e){    if(S->top==MAXSIZE-1)    //棧頂=MAXSIZE-1,即數組的最後一個儲存位置,說明棧滿    {        return ERROR;    }    S->top++;    //棧頂加1    S->data[S->top]=e;    //將元素入棧    return OK;}
(3)出棧操作(從棧頂刪除一個元素)演算法思路:a.判定棧是否為空白;b.將棧頂元素儲存到指標變數e所指向的儲存位置中;c.棧頂減1.實現:若棧不為空白,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
Status Pop(SqStack *S,SElemType *e){    if(S->top==-1)    //空棧    {        return ERROR;    }    *e=S->data[S->top];    S->top--;    return OK;}
(4)兩棧共用空間    棧的順序儲存只准棧頂進出元素,所以不存線上性表插入和刪除時需要移動大量的元素,但是有個缺陷是必須事先確定數組儲存空間大小。當兩個棧資料類型一樣是,我們可以將兩個棧所開闢的空間共用使用。 
A.思想:將棧1的棧底,即為共用空間的棧底(下標為0);另一個棧的棧底為共用棧的末端(下標為數組長度n-1處),其中top1和top2是棧1和棧2的棧頂指標。對於共用棧,若棧2是空棧(top2=n),棧1的top1=n-1,說明棧1滿了;若棧1是空棧(top=-1),棧2的top2=0,說明棧2滿了。即共用棧滿條件:top1+1==top2。B.共用棧空間結構typedef struct{    SElemType data[MAXSIZE];    //定義一個數組儲存空間,大小為MAXSIZE即為棧大小    int top1;    //棧1棧頂指標    int top2;    //棧2棧頂指標}SqDoubleStack;C.共用棧元素入棧操作演算法思路:a.首先判斷共用棧是否棧滿;b.通過stackNumber參數判斷插入哪個棧    若為棧1,則棧頂top1增1,再將元素e入棧;若為棧2,則棧頂top2減1,在將元素e入棧。實現:插入元素e為新的棧頂元素
Status Push(SqDoubleStack *S,SElemType e,int stackNumber){    if(S->top1+1==S->top2)    //判定共用棧是否棧滿(top1+1=top2)    {        return ERROR;    }    if(stackNumber==1)        //棧1有元素進棧,棧頂top1加1        S->data[++S->top1]=e;    else if(stackNumber==2)        S->data[--S->top2]=e;    //棧2有元素進棧,棧頂top2減1    return OK;}
D.共用棧元素出棧操作演算法思想:a.判斷哪一個棧;b.若為棧1,則先將元素賦值給指標變數e指向的空間位置,再棧頂top1減1;    若為棧2,則先將元素賦值給指標變數e指向的空間位置,再棧頂top2增1;實現:若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber){    if(stackNumber==1)    //若刪除元素屬於棧1    {        if(S->top1==-1)     //空棧                  return ERROR;        *e=S->data[S->top1--];    //將元素賦值給e,棧頂再減1    }    else if(stackNumber==2)//若刪除元素屬於棧1    {           if(S->top2==MAXSIZE)     //空棧                  return ERROR;        *e=S->data[S->top2++];    //將元素賦值給e,棧頂再減1      }    return OK;}
升華筆記1:1.棧的順序儲存結構是通過數組來實現的,下標為0為棧底,因為首元素都哦存在棧底變化最小。當棧存在一個元素時,棧頂top為0,如果為空白棧則top=-1,這也是判斷棧是否為空白棧的條件。另外,要區別儲存棧的長度StackSize(MAXSIZE)和儲存位置。2.兩棧共用空間只適用於元素資料類型相同的兩個棧,且入棧是先修改棧頂再元素入棧;出棧是先元素出棧再修改棧頂。

2.棧的鏈式儲存結構及實現


(1)鏈棧的結構//鏈結點:包含資料域和指標域typedef struct StackNode{    SElemType data;                //資料域    struct StackNode *next;    //指標域}StackNode,*LinkStackPtr;//鏈棧結構typedef struct LinkStack{    LinkStackPtr top;    //鏈棧頭結點    int count;                 //結點個數}LinkStack; (2)鏈棧的進棧操作演算法思想:a.先為新結點s開闢一段空間,空間的大小為結點結構大小;b.將要插入的元素值e賦值給新結點s的資料域;c.將原來的棧頂元素賦值給新結點s的後繼d.使棧頂指標指向新結點ee.鏈棧元素增1實現:插入元素e為新的棧頂元素
Status Push(LinkStack *S,SElemType e){    LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));    //開闢一個新的結點空間,大小為結構體StackNode大小    s->data=e;        //將元素e賦值給新結點s的資料域    s->next=S->top;//把當前的棧頂元素賦值給新結點的直接後繼    S->top=s;    //將新的結點s賦值給棧頂指標    S->count++;//鏈棧元素數目加1    return OK;}
(3)鏈棧的出棧操作演算法思想:a.首先判定鏈棧是否為空白棧b.將棧頂指標指向元素資料域資料賦值給ec.將棧頂指標原先指向的元素賦值給pd.再將棧頂指標指向後一個結點,釋放pe.鏈棧元素數目減1實現:若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK
Status Pop(LinkStack *S,SElemType *e){    LinkStackPtr p;    if(StackEmty(*S))    //若空棧        return ERROR;    *e=S->top->data;    //將棧頂元素資料賦值給指標變數e指向空間    p=S->top;                //將棧頂指標指向的結點(棧頂元素)賦值給p    S->top=S->top->next;    //使得棧頂指標下移一位,即此時棧頂指標指向後一個結點    free(p);    //釋放結點p    S->count;    //鏈棧元素數目減1    return OK;}
3.效能分析(1)時間複雜度:棧的順序結構和鏈式結構均為O(1);(2)空間複雜度    棧的順序結構只有資料域,空間複雜度小,但事先需要確定一個固定的長度,可能會存在記憶體空間浪費問題;    棧的鏈式儲存結構每個元素具有資料域和指標域,空間複雜度稍複雜,同時也增加了一些記憶體開銷,但對於棧的長度無限制。(3)如果棧的使用過程中元素變化不可預料,有時很小,有時非常大,那麼最好是用鏈棧;反之,如果它的變化在可控範圍內,建議使用順序棧效能會更高些。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.