《大話數據結構》讀書筆記(四)
4.1 棧的定義
4.1.1 棧的概念
棧(stack)是限定僅在表尾進行插入和刪除操作的線性表。
我們允許插入和刪除的一端稱為棧頂(top),另一端稱為棧底(bottom),不含任何數據元素的棧稱為 空棧。棧又稱為後進先出的線性表,簡稱LIFO結構。
理解棧的定義需要註意:
1.他是一個線性表,也就是說,棧元素具有線性關系,即前驅後繼關系。是一種特殊的線性表,他的特殊之處就在於限制了這個線性表的插入和刪除位置,它始終只在棧頂進行,這也就使得:棧底是固定的,最先進棧的只能在棧底。
棧的插入操作,叫作進棧,也稱壓棧、入棧。
棧的刪除操作,叫作出棧,也有叫作彈棧。
4.1.2 進棧出棧變化形式
最先進棧的元素,是不是就只能是最後出棧呢?
答案是不一定,要看什麽情況。棧對線性表的插入和刪除的位置進行了限制,並沒有對元素進出的時間進行限制,也就是說,在不是所有元素都進棧的情況下,事先進去的元素也可以出棧,只要保證是棧頂元素出棧就可以。
案例:我們現在是有3個整型數字元素1、2、3依次進棧,會有哪些出棧次序?
第一種:1、2、3進,在3、2、1出。出棧次序為 321.
第二種:1進,1出,2進,2出,3進,3出。出棧次序為:123.
第三種:1進,2進,2出,1出,3進,3出。出棧次序為:213.
第四種:1進,1出,2進,3進,3出,2出。出棧次序為:132.
第五種:1進,2進,2出,3進,3出,1出。出棧次序為:231.
4.2棧的抽象數據類型
ADT 棧(stack)
DATA
同線性表。元素具有相同的類型,相鄰元素具有前驅和後繼關系。
Operation
InitStack ( *S ) :初始化操作,建立一個空棧S。
DestroyStack( *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
4.3 棧的順序存儲結構及實現
4.3.1 棧的順序存儲結構
棧的結構定義
typedef int SElemType; /* SElemType類型根據實際情況而定,這裏假設為int */
typedef struct
{
SElemType data[MAXSIZE] ;
int top; /* 用於棧頂指針 */
}SqStack;
4.3.2 棧的順序存儲結構--進棧操作
進棧的push
/* 插入元素e 為新的棧頂元素 */
status push ( SqStack *S ,SElemType e )
{
if( s->top == MAXSIZE -1 ) { /* 棧滿 */
return ERROR;
}
S -> top ++; /* 棧頂指針加一 */
S ->data[ S -> top ] = e; /* 將新插入元素復制給棧頂空間 */
return OK;
}
4.3.3 棧的順序存儲結構----出棧操作
/* 若棧不空,則刪除S的棧頂元素,用 e 返回其值,並返回OK;否則返回ERROR */
status Pop ( SqStack *S , SElemType *e )
{
if ( S ->top == -1 ){
return ERROR;
}
*e = S -> data[S -> top ]; /* 將要刪除的棧頂元素賦值給e */
S -> top --; /* 棧頂指針減一 */
return OK;
}
進棧和出棧都沒有涉及循環語句,因此時間復雜度均為 O( 1 )。
4.4 兩棧共享空間
/* 兩棧共享空間結構 */
typedef struct
{
SElemType data[MAXSIZE];
int top1; /* 棧1 棧頂指針 */
int top2; /* 棧2 棧頂指針 */
}SqDoubleStack;
對於兩棧共享空間的push方法,我們除了要插入元素值參數值外,還需要添加一個判斷棧1還是棧2的參數stackNumber。
/* 插入元素 e 為新的棧頂元素 */
status push ( SqDoubleStack *S , SElemType e, int stackNumber )
{
if ( S -> top1 +1 == top2 ) { /* 棧已滿,不能在push了 */
return ERROR;
}
if ( stackNumber == 1 ){ /* 棧1 有元素 */
S -> data[ ++S -> top1 ] = e; /* 若棧1則先top1 +1 後給數據元素賦值 */
} else if ( stackNumber == 2 ){ /* 棧2有元素 */
S ->data[ -- S -> top2 ] = e; /* 若棧2則先 top2 - 1後給數據元素賦值 */
}
return OK;
}
對於兩棧共享空間的pop方法,參數就只是判斷棧1 和棧2 的參數stackNumber。
/* 若棧不空,則刪除S的棧頂元素,用e 返回其值,並返回ok;否則返回error */
status pop ( SqDoubleStack *S , SElemType *e , int stackNumber )
{
if ( stackNumber == 1 ){
if ( S ->top1 == -1 ){
return ERROR; /* 說明棧1已經是空棧了,溢出 */
}
*e = S ->data [ S->top1 -- ]; /* 將棧1的棧頂元素出棧 */
}else if ( stackNumber == 2 ){
if ( S ->top2 == MAXSIZE ){
return ERROR; /* 說明棧2已經是空棧了,溢出 */
}
*e = S ->data [ S->top2 ++ ]; /* 將棧2的棧頂元素出棧 */
}
return OK;
}
《大話數據結構》讀書筆記(四)