棧
- 棧的定義:棧是操作受限的線性表
- 棧頂:允許操作的一端
- 棧的特性:先進後出
- 數據結構:邏輯結構+存儲結構+數據運算
順序棧
- 順序棧定義:採用順序存儲,地址連續的存儲單元以及指向棧頂元素的指針
- 存儲類型
#define MAXSIZE 70
typedef struct{
int num[MAXSIZE];
int top;//指向棧頂元素的指針
}SqStack;
#define MAXSIZE 70
typedef struct{
int data[MAXSIZE];
int top;//指向棧頂元素的指針
}SqStack;
//順序棧的基本運算
//初始化棧 不返回
void initSqStack(SqStack &S){
S.top=-1;//縮寫爲S,stack的意思
}
//判空
bool Empty(SqStack S){
if(S.top==-1)
return true;
return false;
}
//入棧錯誤寫法
void push(SqStack &S,int x){//返回trueorfalse
S.data[++S.top]=x;//先判斷滿
}
//入棧
bool push(SqStack &S,int x){
if(S.top==MAXSIZE-1){
return false;
}
else{
S.data[++S.top]=x;
return true;
}
}
//出棧
#define MAXSIZE 70
typedef struct{
int data[MAXSIZE];
int top;//指向棧頂元素的指針
}SqStack;
//順序棧的基本運算
//初始化棧 不返回
void initSqStack(SqStack &S){
S.top=-1;//縮寫爲S,stack的意思
}
//判空
bool Empty(SqStack S){
if(S.top==-1)
return true;
return false;
}
//入棧錯誤寫法
void push(SqStack &S,int x){//返回trueorfalse
S.data[++S.top]=x;//先判斷滿
}
//入棧
bool push(SqStack &S,int x){
if(S.top==MAXSIZE-1){
return false;
}
else{
S.data[++S.top]=x;
return true;
}
}
//出棧
共享棧
- top1=0//top2=maxsize時棧空
- top1-top0=1時佔滿
- 0號棧入棧,top先加一在賦值,1號棧入棧,top先減一在賦值
- 共享棧是爲了更好的利用存儲空間,對存儲效率沒什麼影響存取數據的時間複雜度均是O1
棧的鏈式存儲結構
- 鏈棧的優點是便於多個棧共享存儲空間和提高效率
- 通常不會有棧滿的情況
- 是一個操作只能在單鏈表表頭進行的鏈表
- 規定鏈棧沒有頭節點
- 棧的鏈式存儲類型:
1.注意定義只用定義鏈棧的節點類型,使用結構體,包括數據域和指針域,和單鏈表的定義時一樣的,區別是需要定義這個結構體的指針型,這裏單鏈表是不同的 。定義這個指針的作用是用來定義棧頂指針的,也就是鏈表中的頭指針,只不過鏈表中的頭指針是在定義結構體之後定義的,這裏值直接定義了一個指針類型Lstack。
2、初始化返回bool類型就可,傳遞參數是頭節點指針的引用類型,也就是top指針,這裏和不帶頭節點的單鏈表的一樣一樣的,真的是完全一樣一樣的,你可以這麼理解,鏈表中每一個節點都有一個指針指向它,對於帶頭節點的鏈表,先定義一個頭指針,在爲這個頭指針開闢一個空間節點,讓這個指針指向這個節點,但是這個節點不放數據,對於不帶頭節點·的指針,就定義一個頭指針,然後讓這個頭指針指向一個新開闢的節點,我們的鏈棧就和這個一樣,定義一個top指針,讓他指向第一個節點,也就是棧頂指針指向棧頂元素總而言之,鏈表,每一個節點都要有對應的指針,每一個指針都要有指向的節點我真是太聰明瞭,我可以出教輔了
//鏈棧結點結構
typedef struct LSNode{
ElemType data;//數據域
struct LSNode *next; //指針域
}LSNode,*LStack;
//初始化
bool InitLSN(LStack &L){
if(NULL==(L=(LStack)malloc(sizeof(LSNode))))
return false;
L->next=NULL;//頭結點的next域爲空
return true; }
//判斷棧是否爲空
Status notnull(LStack L){
//判斷棧是不是空
if(L==NULL)
return OK; //如果空,返回OK,即爲1
else
return ERROR;
}
//入棧
Status POP_LSN(LStack &L,ElemType e){
LStack t;
t = (LStack)malloc(sizeof(LSNode)); //開闢存儲空間
if(NULL == t) return OVERFLOW;//失敗
t->data = e;
t->next = L;//指向原棧頭
L = t;
return OK;
}
//出棧
Status PUSH_LSN(LStack &L,ElemType e){
LStack t;
if(NULL == L) return OVERFLOW; //空棧
t = L; //指向棧頂元素結點
e = L->data; //用e返回棧頂元素值
printf("%d",e);
L = L->next; //刪除棧頂元素結點
free(t); //釋放結點
return OK;
}
習題
這道題非常的有意義。首先,這個棧頂和棧底。和這個鏈表的關係。如果用一個單鏈表當作棧,J那麼鏈表頭。和鏈表尾。哪一個適合做棧頂。檔案室鏈表頭。如果是鏈表尾的,那麼每次插入元素之後,電錶爲的指針繪製成空的。怎麼刪除的時候?發現沒有辦法刪除。鏈表的尾部沒有辦法刪除。因爲找不到前驅指針。但是鏈表頭部是可以的。
第二個點。就是帶頭結點和不帶頭結點的。題目中指向棧頂。那就是不帶頭結點的。第一個元素就是佔地。如果帶頭結點的,Top指向的不是棧頂。。是上面的一個。
解析:
1、抽象數據類型:描述數據的邏輯結構和抽象運算,可以看都有三個元素,數據(數據對象)邏輯結構(數據關係)抽象運算(基本操作)棧和隊列的基本操作不同所以抽象數據類型不同
2、邏輯結構:線性和非線性,存儲結構:順序和和鏈式
解析:首先你要明確top是返回棧頂元素而不是去除棧頂元素,我不明白的就是應該用引用形式纔對的
解析:
1、公式記住
2、cab是不能實現的,一般大的在前的話,後面的都是逆序,比如,c比a和b大,c在前
,那麼ab必須是逆序,有棧的特點可以很快的得到結論
這個題注意的是出棧順序是
2第一,1最後