1. 程式人生 > >資料結構---棧和佇列(結構體實現)

資料結構---棧和佇列(結構體實現)

棧(LIFO)

棧(stack)是一種只能在一端進行插入或刪除操作的線性表。

棧頂(top):允許進行插入、刪除操作的一端

棧底(bottom):另一端稱為棧底

進棧或入棧(push):插入操作

出棧或退棧(pop):棧的刪除操作

n個不同元素通過一個棧產生的出棧序列的個數為\frac{1}{n+1}C^{n}_{2n}

順序棧(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)。這裡採用帶頭結點的單鏈表來實現鏈棧。

鏈棧的優點是不存在棧滿上溢位的情況。規定棧的所有操作都是在單鏈表的表頭進行的(因為帶有頭結點,在其後插入或刪除節點都很方便,時間複雜度為O\left ( 1 \right )).