順序棧的存儲結構(兩種描述方法對比)


1.順序棧的結構特點

   順序棧是用順序存儲結構的棧。嗯,賊官方啊,這句話是啥意思呢,就是在內存中用一組地址連續的存儲單元依次存放從棧底到棧頂的元素,one by one,都在一塊知道不。

棧的聲明代碼如下:

typedef struct {
    ElemType data[MaxSize];
    int top;    //存放棧頂元素在數組中的下標
}SqStack;

開始學的時候真的好迷,干嘛把top叫做指針啦,它又沒存放地址來着。。。。不過能通過它來找到對應元素,也算是起了指針的作用吧。

在課本上采用了另一種描述:

就沒有ElemType的數組定義了,而是用了兩個指針

typedef struct{
    ElemType *base;
    ElemType *top;
    int MaxSize;    //當前已分配的空間
}SqStack;

讓base指向棧底不動,emmm,不過用數組下標就可以很容易找到棧底啊,為嘛還要用base來保存它的地址啊(* ̄︶ ̄)

那是因為這種定義里面根本就沒有數組啊蠢貨!!元素的訪問只能通過指針啊!

2.順序棧的基本算法

1)初始化棧

  按照課本上的定義代碼,初始化算法

Status InitStack(SqStack &S){
  //構造一個空棧
  S.base  =(ElemType *)malloc(MaxSize*sizeof(ElemType));
  if(!S.base)   //存儲分配失敗
    exit(0);
  S.top=S.base;
  S.stacksize = MaxSize;
  return 1;
}//InitStack;

按照將ElemType有數組的定義里面,初始化操作是這樣的

void InitStack(SqStack &s){
    s=(SqStack *)malloc(sizeof(SqStack));
    s->top = 0;
}

要注意到兩種算法里面用malloc()函數里面開辟新的空間的不同點

2)進棧Push(SqStack &S,ElemType e);

int Push(SqStack &S,ElemType e){
    //插入元素e為新的棧頂元素
    if((S.top-S.base) >= S.stacksize){  //棧滿,追加儲存空間
        S.base = (ElemType *)realloc(S.base,
                                     (S.stacksize+STACKINCREASEMENT)*sizeof(ElemType));
    
    if(!S.base)
        exit(0);    //存儲空間分配失敗
    S.top = S.base +S.stacksize;    
    //此時stacksize還是原來的值木有變大,指向的是沒有增加空間的棧頂
    S.stacksize +=STACKINCREASEMENT;
    }
    *S.top++ = e;
    return 1;
}//Push

話說,課本上雖然寫的很詳細,很內啥,健壯??但是真的不好看懂啊,前面那么一長串,就是為了檢查空間滿沒滿,滿了在加,很容易迷失重點的好嘛!

還有將e賦值的時候,因為用到了top指針,所以是  *top=e;  喲

還是看一下簡易版,雖然寒酸了點,但是可以很快get到重點啊

int Push(SqStack &S,ElemType e){
    //將數據元素e壓入棧頂
    if(S.top==MaxSize)
        return 0;
    S.elem[S.top]=e;
    S.top++;
    return 1;
}

其實就是one插入元素two加指針

3)出棧操作Push(SqStack &S, ElemType e);

先來看看課本上的實現

int Pop(SqStack &S,ElemType &e){
//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回1,否則返回0
if(S.top == S.base)
    return 0;
    e = *--S.top;
    return 1;
}//Pop

這個很好理解啦。要注意的點就是先減指針再取值,不然沒有值取啊恍恍惚惚

現在看一下第一種定義里面的實現

int Pop(SqStack &s,ElemType &e){
//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回1,否則返回0
    if(S.top !=0)
        return 0;
     else{
        S.top--;
        e= S.elem[S.top];
     }   
     return 1;
}

是不是也十分明了呢

4)取棧頂元素GetTop(SqStack &S,ElemType &e)

int GetTop(SqStack &S,ElemType &e){
//若棧不空,則用e返回棧頂元素並返回1,否則返回0
    if(S.top == S.base)
        return 0;
    e = *(S.top - 1);
    return 1;
}//GetTOP

其實,代碼里面有好多巧妙的東西呀,只有打一遍才能發現~比如

num1:為什么這里取元素的時候top指針不是自減一呢?而是top-1

答:因為我們不希望改變top指針的指向啊,用top-1既可以得到棧頂元素,top自己又沒有改變,完美!

num2:為什么上面兩個代碼一個是 e = *--S.top;另一個是 *S.top++ = e;呢(課本上的push和pop算法核心)?

答:因為取元素的時候要先減指針再賦值,而且涉及到運算級的優先問題,*的優先級大於--,所以不能寫成,e=--*top;

接下來是另一個定義的取棧頂元素

int GetTop(SqStack &S,ElemType &e){
//若棧不空,則用e返回棧頂元素並返回1,否則返回0
    if(S.top == 0)
        return 0;
    e=S.elem[S.top-1];
        return 1;
}

嗯,最基本的操作就在這里了,下一次寫應用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM