程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SyBase數據庫 >> SyBase教程 >> 數據結構-棧的鏈式存儲

數據結構-棧的鏈式存儲

編輯:SyBase教程

數據結構-棧的鏈式存儲


棧的鏈式存儲

1 棧的鏈式表示
棧的鏈式存儲結構稱為鏈棧,是運算受限的單鏈表。其插入和刪除操作只能在表頭位置上進行。因此,鏈棧沒有必要像單鏈表那樣附加頭結點,棧頂指針top就是鏈表的頭指針。圖3-4是棧的鏈式存儲表示形式。

鏈棧的結點類型說明如下:
typedef  struct  Snode
{  ElemType   data ;
struct Snode  *next ;
} SNode, *Link_Stack ;

鏈棧基本操作的實現

2  鏈棧基本操作的實現
(1) 棧的初始化
SNode *Init_Link_Stack(void)
{  SNode *top ;
top=(SNode *)malloc(sizeof(SNode)) ;
if(top==NULL)
   return ERROR;
else
{   top->next=NULL ; 
     return(top) ;}
}
(2)  壓棧(元素進棧)
Status push(SNode *top , ElemType  e)
{   SNode *p ;
p=(SNode *)malloc(sizeof(SNode)) ; 
if (!p)  return  ERROR; 
/*  申請新結點失敗,返回錯誤標志 */
p->data=e ; 
p->next=top->next  ; 
top->next=p ;    /*  鉤鏈  */
return OK;
}注意:1、與頭插入法建立鏈表類似
 2、此處top結點的數據域不放數據,也可設置成存放數據,程序如何改?
(3)  彈棧(元素出棧)
ElemType pop(SNode *top )
/*  將棧頂元素出棧  */
{   SNode *p ;
ElemType  e ;
if  (top->next==NULL )
return ERROR ;    /*  棧空,返回錯誤標志    */
p=top->next ; e=p->data ;    /*  取棧頂元素  */
top->next=p->next ;     /*  修改棧頂指針  */
free(p) ; 
return OK ;
}

輸出棧中元素

void print(SqStack *S)
{   
    int c;
    cout<<"輸出棧中元素"<<endl;

    for( c=S.top--;c>=0;c--)
    {
        cout<<S.bottom[c]<<endl;
    }

}

棧與遞歸調用的實現

棧的另一個重要應用是在程序設計語言中實現遞歸調用。
遞歸調用:一個函數(或過程)直接或間接地調用自己本身,簡稱遞歸(Recursive)。
遞歸是程序設計中的一個強有力的工具。因為遞歸函數結構清晰,程序易讀,正確性很容易得到證明。
為了使遞歸調用不至於無終止地進行下去,實際上有效的遞歸調用函數(或過程)應包括兩部分:遞推規則(方法),終止條件。

系統實現遞歸需要一個系統棧 (遞歸工作棧) ,用於在程序運行時處理函數調用。
系統棧是一塊特殊的存儲區。當一個函數被調用時,系統創建一個工作記錄,稱為棧桢(stack frame),並將其置於棧頂。
初始時只包括返回地址和指向上一棧的指針。
當該函數調用另一個函數時,該函數的局部變量、參數將加到它的棧桢中。
一個函數運行結束,將從棧中刪除它的棧桢,程序控制返回原調用函數繼續執行下去。

從被調函數返回調用函數的一般步驟
若棧為空,則執行正常返回。
否則,從棧頂彈出一個工作記錄,將“工作記錄”中的參數值、局部變量值賦給相應的變量;。
讀取返回地址,將函數值賦給相應的變量。
轉移到返回地址。

遞歸算法的優缺點

優點
程序非常簡潔而清晰,並且易於分析,可讀性較強。
缺點
費空間:系統實現遞歸需要一個系統棧,用於在程序運行時間處理函數調用。
費時:局部變量、形式參數和返回地址的進棧、出棧以及參數的傳遞需要費時,而且遞歸中的重復計算也很浪費時間。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved