數據結構:順序棧的實現


數據結構:順序棧的實現

1、快速開始

  棧是一種遵循元素后進(Push)先出(Pop)規則的線性表,即最后加入的元素最先出來,它的實現可以用數組或者鏈表。

  

  

  它的特點如下:

  • 后入先出,先入后出。
  • 除了頭尾節點之外,每一個元素有一個前驅,有一個后繼。  

 

2、實現棧

  我們已經說過了,棧是一種線性表,故其底層是基於數組或者鏈表的。那么,我們的重點是維護一種規則,即后進先出。

  我們始終要有一個變量L來記錄最后一個元素的位置:

  • 當壓入時,將新元素插入到L位置之后,然后更新L,即L+1.
  • 當彈出時,將L位置元素進行刪除,然后更新L,即L-1。
    •  

   也正是因為,我們使用的是線性表,正好可以利用其尺寸來表示L,即線性表的大小可以表示最后一個元素的位置。

2.1、棧的實現 

class MyStack {
    private List<Integer> data;               // 存儲元素
    public MyStack() {
        data = new ArrayList<>();
    }
    /**插入一個元素到棧中. */
    public void push(int x) {
        data.add(x);
    }
    /**檢查是否為空 */
    public boolean isEmpty() {
        return data.isEmpty();
    }
    /**到達棧頂. */
    public int top() {
        return data.get(data.size() - 1);
    }
    /** 刪除一個元素. 操作成功返回true. */
    public boolean pop() {
        if (isEmpty()) {
            return false;
        }
        data.remove(data.size() - 1);
        return true;
    }
};

  

3、C語言版本實現

3.1、對棧的結構定義:

typedef struct
{
   int *base; 
   int *top; 
   int stacksize;    
}SqStack;

說明:

    1.base表示棧底指針,在判斷出棧、初始化和重新分配空間的時候需要用到。

    2.top表示棧頂指針,是棧最關鍵和核心的組成,入棧時top向上移動,出棧時top向下移動。

    3.此處的stacksize並不表示當前的棧中的元素數量,而是表示棧的容量,也就是能裝多少個元素。

3.2、初始化棧:

int initStack(SqSatck *S)
{
    S->base=(int*)malloc(100*sizeof(int));
    if(!S)
         return 0; //0代表操作失敗
    S->top=S->base;
    stacksize=100;
    return 1; //1代表操作完成
}

說明:

    1.順序棧初始化無非就是給棧分配連續的內存空間,base是棧底指針,在上面提到過,它用來指示一段連續的內存空間的首地址,也就是用來初始化。

    2.分配空間不意味着一定會有那么多空間,所以判斷也不可缺少。

    3.分配空間后,base和top的地址應該一致,此時top還沒有移動。

3.3、壓棧

int push(SqStack * S,int elem)
{
  if(S->top-S->base>=S->stacksize)
  {
        S->base=(SElemType *)
                realloc(S->base,(S->stacksize+10)*sizeof(SElemType)); //10代表增量,你可以使用宏定義,方便后續修改。
        if(!S->base)
            return 0;
        S->top=S->base+S->stacksize;
        S->stacksize+=10
  }
  *S->top++=elem;
  return 1;
}    

  說明:

    1.壓棧是棧的核心操作,關鍵步驟無非是*S->top++=elem;但是在進行此步操作時,一定要判斷棧是否超出容量。

    2.如果棧超出容量,則要在進行原空間的基礎上重新分配空間,realloc是關鍵的命令。

  realloc 
    原型:extern void *realloc(void *mem_address, unsigned int newsize); 
    用法:#include <stdlib.h> 有些編譯器需要#include <alloc.h> 
    功能:改變mem_address所指內存區域的大小為newsize長度。 
    說明:如果重新分配成功則返回指向被分配內存的指針,否則返回空指針NULL。 
    當內存不再使用時,應使用free()函數將內存塊釋放。 

    3.分配空間以后,在修改stacksize之前,top應該保持在容量頂端,S->top=S->base+S->stacksize;

2.4出棧

int pop(SqStack *q)
{
    if(S->top==S->base)
          return 0;
    return *S->--top;;
}

說明:

    1.出棧是簡單操作,其實這里並沒有完美的實現這個效果,你應該考慮到如果在擴容后又迅速減小,會造成大量的空間浪費。 

2.5遍歷棧

int printfStack(SqStack *S)
{
    int *p=S->base;
    puts("輸出棧");
    for(p;p!=S->top;p++)
    {
        printf("***%d",*p);
    }
}

  


免責聲明!

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



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