(轉載)數據結構-棧

即後進先出(LIFO)的線性表

棧的常用算法有置棧空、判棧空、進棧、出棧、取棧頂等。

 

1.順序棧

結構如下:

typedef struct

{

       DataType data[MAXSIZE];

       int top;

}SeqStack;

即,它需要一個棧頂top。

 

相關算法的關鍵步驟如下

//置棧空

void Initial(SeqStack *S)

{ S->top=-1; }

 

//判棧空

int IsEmpty(SeqStack *S)

{ return S->top==-1; }

 

//進棧

void Push(SeqStack *S,DataType x)

{ S->data[++S->top]=x; }

 

//出棧

DataType Pop(SeqStack *S)

{ return S->data[S->top--]; }  //棧頂減1,返回已經出棧的元素

 

2. 鏈棧

結構如下:

typedef struct node

{

       DataType data;

       struct node *next;  //知道結構名稱的作用了吧,這裏就要用到node

}LinkStack;

typedef struct

{

       LinkStack *top;

}TopNode;

       我們需要一個專門指向棧頂的指針(注意不是棧頂指針,而是指向棧頂的指針)。所以我們定義一個結構體TopNode,T.top就是指向棧頂的指針。或者我們用一個數組也行:

LinkStack * TopNode[1];

       那麼TopNode[0]就用來作指向棧頂的指針,函數的形參寫成LinkStack * TopNode[],傳實參的時候用數組名TopNode,在函數內部就可以使用TopNode[0]。這種方面類似於函數形參是一個結構體TopNode *T,那麼傳實參的時候傳&T,在函數內部使用T->top。

       至於用數組和用結構哪個好,我覺得用結構還要用typedef定義類型,效率可能稍低。所以,用結構含義清楚,用數組效率更高。

/*頭插法特點:無頭結點,top指針始終指向最後插入的那個元素*/

LinkStack *CreListTou()

{ int x; LinkStack *S; TopNode T;

       T.top=NULL;

       scanf("%d",&x);

       while(x!=-1)    //輸入-1代表結束

       {

              S=malloc(sizeof(LinkStack));

              S->data=x;

 

              /*關鍵代碼: S->next等於T.top ,然後T.top反轉來等於S*/

              S->next=T.top;

              T.top=S;  //修改top指向

              scanf("%d",&x);

       }

       return T.top;

}

 

//置棧空

void Initial(TopNode *T)

{ T->top=NULL; }

 

//進棧

void Push(TopNode *T,DataType x)

{

       LinkStack *S;

       S=malloc(sizeof(LinkStack));

    S->data=x;

 

       //與建棧時相同,將S的後繼設置爲原棧頂,S成爲新的棧頂

    S->next=T->top;

       T->top=S;

}

 

//出棧

DataType Pop(TopNode *T)

{

       LinkStack *p;

       DataType x;

 

       /*關鍵算法:先把T.top指向原棧頂的next,然後free掉原棧頂*/

       p=T->top;

       x=p->data;

       T->top=p->next;// T.top指向原棧頂的next

       free(p);

       return x;

}

 

注意上面列出的只是算法的關鍵部分,並不完整,刪減了一些“棧空”“棧滿”的判斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章