資料結構---棧和佇列(結構體實現)
棧(LIFO)
棧(stack)是一種只能在一端進行插入或刪除操作的線性表。
棧頂(top):允許進行插入、刪除操作的一端
棧底(bottom):另一端稱為棧底
進棧或入棧(push):插入操作
出棧或退棧(pop):棧的刪除操作
n個不同元素通過一個棧產生的出棧序列的個數為。
順序棧(sequential stack)及其基本運算的實現
棧可以像線性表一樣採用順序儲存結構進行儲存,即分配一塊連續的儲存空間來存放棧中的元素,並用一個變數(如top)指向當前的棧頂元素,以反映棧中元素的變化。
順序棧(SqStack)的宣告
#define MaxSize 50 typedef int ElemType; typedef struct{ ElemType data[MaxSize]; 連續記憶體空間存放棧中元素 int top; //存放棧頂元素在data陣列中的下標 }SqStack;
採用棧指標 s (不同於棧頂指標top)的方式建立和使用順序棧。
初始時,為空棧,設定s->top = -1,有:
棧空的條件:s->top == -1;
棧滿的條件:s->top == MaxSize - 1;
元素e的進棧操作:先將棧頂指標top增1,然後將元素e放在棧頂指標處。
出棧操作:先將棧頂指標top處的元素取出放在e中,然後將棧頂指標減1。 \\棧頂指標top實際上是棧頂元素的陣列下標
初始化棧 initStack(&s)
建立一個空棧,由s指向它。即分配一個順序棧空間,並將棧頂指標設定為-1。
void initStack(SqStack* &s){ s = (SqStack*)malloc(sizeof(SqStack)); //分配空間,首地址存放在s中 s->top = -1; }
銷燬棧 DestroyStack(&s)
void DestroyStack(SqStack* &s){
free(s);
}
判斷棧是否為空 StackEmpty(&s)
運用棧空判斷條件是否成立
bool StackEmpty(SqStack *s){
return s->top == -1;
}
進棧 Push(&s, e)
要先判斷棧是否已滿
bool Push(SqStack *s, ElemType e){ if(s->top == MaxSize-1) return false; else s->top++; s->data[s->top] = e; return true; }
出棧 Pop(&s, &e)
首先判斷棧是否為空
bool Pop(SqStack* &s, ElemType &e){
if(s->top == -1) return false;
else
s->data[s->top] = e;
s->top--;
return false;
}
取棧頂元素 GetTop(s, &e)
首先判斷棧是否為空
bool GetTop(SqStack *s, ElemTypee &d){
if(s->top == -1) return false;
e = s->data[s->top];
return true;
}
應用:設計一個演算法利用順序棧判斷一個字串是否為對稱串。所謂對稱串指從左向右讀和從右向左讀的序列相同。
#include <iostream>
using namespace std;
#define MaxSize 50
typedef char ElemType;
typedef struct {
ElemType data[MaxSize];
int top;
}SqStack;
void initStack(SqStack* &s) {
s = (SqStack*)malloc(sizeof(SqStack));
s->top = -1;
}
void Push(SqStack* &s, ElemType e) {
if (s->top != MaxSize - 1) {
s->top++;
s->data[s->top] = e;
}
}
void Pop(SqStack* &s, ElemType &e) {
if (s->top != -1) {
e = s->data[s->top];
s->top--;
}
}
void ArrayCreateStack(SqStack* &s, ElemType a[], int n) {
initStack(s);
for (int i = 0; i < n; i++)
Push(s, a[i]);
}
bool SymmetricArray(ElemType a[], int n) {
SqStack *s;
ArrayCreateStack(s, a, n);
for (int i = 0; i < n/2; i++) {
ElemType j;
Pop(s, j);
if (j != a[i]) return false;
}
return true;
}
int main() {
char a1[] = "asdfggfdsa";
char a2[] = "1234567890";
cout << SymmetricArray(a1, 10) << endl;
cout << SymmetricArray(a2, 10) << endl;
system("pause");
}
共享棧(share stack)
用一個數組來實現兩個棧。讓一個棧的棧底為陣列的始端,即下標為0處;另一個棧的棧底位陣列的末端,即下標為MaxSize-1。這樣, 在兩個棧中進棧時,棧頂向中間伸展。
棧空的條件:棧1空為 top1 == -1;棧2空為 top2 == MaxSize。
棧滿的條件:top1 == top2 - 1。
元素e進棧操作:進棧1操作為{ top1++;data[top1] = e; };進棧2操作為{ top2--;data[top2] = e; }。
出棧e操作:出棧1操作為{ e = data[top1];top1--; };出棧2操作為{ e = data[top2];top2++; }
該共享棧用data、top1、top2來標識。
共享棧的宣告
typedef struct{
ElemType data[MaxSize];
int top1, top2;
}DStack;
在實現共享棧的基本運算演算法時需要增加一個形參i,用來指出是對哪個棧進行操作。
鏈棧及其基本運算的實現
採用鏈式儲存結構的棧稱為鏈棧(linked stack)。這裡採用帶頭結點的單鏈表來實現鏈棧。
鏈棧的優點是不存在棧滿上溢位的情況。規定棧的所有操作都是在單鏈表的表頭進行的(因為帶有頭結點,在其後插入或刪除節點都很方便,時間複雜度為).