北航軟件工程專業考研991數據結構總結:
四、堆棧與隊列
1.堆棧與隊列的基本概念與基本操作;
2.堆棧與隊列的順序存儲結構與鏈式存儲結構的構造原理;
3.在不同存儲結構的基礎上對堆棧與隊列實施插入與刪除等基本操作的算法設計;
4.堆棧和隊列在解決實際問題中應用。
1、堆棧與隊列的基本概念與操作
1)、堆棧的基本概念與操作
堆棧:只能在表的一端進行操作的線性表,一般的操作就是插入和刪除,允許操作的一端稱爲棧頂,棧頂元素由棧頂指針給出,沒有元素時爲空棧
後進先出,先進後出
插入(入棧,進棧)
刪除(出棧,退棧)
判空
判滿
檢索當前棧頂元素
特殊性:1、操作時一般線性表的子集;2、插入和刪除的位置受到限制
2)、隊列的基本概念與操作
隊列:隊列簡稱隊,是一種只能由一端進行插入,另一端進行刪除的線性表。進行插入的一端稱爲隊尾,用rear表示,刪除的一端稱爲隊頭,用front指針表示
先進先出,後進後出
插入(進隊,入隊)
刪除(出隊,退隊)
判空
檢索當前隊頭元素
創建空隊
特殊性:1、操作時一般線性表的子集;2、插入和刪除的位置受到限制
2、堆棧與隊列的順序存儲結構與鏈式存儲結構的構造原理
1)、堆棧的順序存儲結構
一維數組SCACK[0..n-1],定義一個整型變量給出棧頂元素,但是不同於數組,數組時靜態結構,堆棧是動態結構
溢出:上溢:棧滿時進行插入操作 top = n-1;下溢:棧空時進行刪除操作 top = -1
定義:
#define M 1000
int STACK[M];
int top = -1; //初始的時候top爲-1,表示棧空
2)、堆棧的鏈式存儲結構
用線性鏈表表示,棧頂指針爲NULL是爲空
typedef struct node{
int data;
struct node *link;
}STNode, *STLink;
3)、隊列的順序存儲結構
一維數組QUEUE[0..n-1],兩個變量front和rear指出隊頭和隊尾元素的位置。
約定:rear指出實際隊尾元素的位置
front指出隊頭元素的前一個位置
初始隊列爲空front = -1 ; rear = -1;
判斷隊列爲空的條件:front = rear;
#define M 1000
int QUEUE[M];
int front, rear;
4)、隊列的鏈式存儲結構
用線性鏈表表示,rear指出隊尾,front指出隊頭
空隊列 front = NULL;
typedef struct node{
int data;
struct node *link;
}QNode, *QLink;
3、在不同存儲結構上對堆棧和隊列進行插入和刪除操作的算法設計
1)、順序存儲結構上對堆棧進行操作
初始化
void Init(int &top)
{
top = -1;
}
判空
int Empty(int top)
{
return top == -1;
}
判滿
int FULL(int top)
{
return top == M-1;
}
插入(進棧)
int Push(int Stack[], int &top, int element)
{
if(FULL(top)
return 0;
else{
Stack[++top] = element;
return 1;
}
}
刪除(出棧)
int Pop(int Stack[], int &top, int element)
{
if(Empty(top))
return 0;
else{
element = Stack[top--];
return 1;
}
}
2)、鏈式存儲上對堆棧進行操作
初始化
void Init(STLink &top)
{
top = NULL;
}
判空
int Empty(STLink top)
{
return top == NULL;
}
插入(進棧)不用判滿
int Push(STLink &top, int item)
{
STLink p;
if(!(p = (STLink)malloc(sizeof(STNode))))
return 0;
else{
p->data = item;
p->link = top;
top = p;
return 1;
}
}
刪除(出棧)
int Pop(STLink &top, int &item)
{
STLink p;
if(Empty(top))
return 0;
else{
p = top;
item = p->data;
top = top->link;
free(p);
return 1;
}
}
3)、在順序存儲結構上對隊列進行操作
初始化
void Init(int &front, int &rear)
{
front = -1;
rear = -1;
}
判空
int Empty(int front, int rear)
{
return rear == front;
}
插入
int ADDQ(int Queue[], int &rear, int item)
{
if(rear == M-1) //假溢出
return 0;
else{
Queue[++rear] = item;
return 1;
}
}
刪除
int DELQ(int Queue[], int &front, int rear, int &item)
{
if(Empty(front, rear))
return 0;
else{
item = Queue[--front];
return 1;
}
}
循環隊列:將隊列想象成頭尾相連的表,使得隊頭刪除的元素的空間能夠儘可能被利用
算法1:刪除之後將每個元素前移一位。
缺點:浪費空間
算法2:求餘
添加:
int ADDQ(int Q[], int &rear, int &front, int item)
{
if((rear+1)%M == front)
return 0;
else{
Q[++rear%M] = item;
return 1;
}
}
刪除:
int DELQ(int Q[], int &front, int &rear, int &item)
{
if(front == rear)
return 0;
else{
front = (front + 1)%M;
item = Q[front];
return 1;
}
}
4)、在鏈式存儲結構上對隊列進行操作
初始化
void Init(QLink front, QLink rear)
{
front = NULL;
rear = NULL;
}
判空
int Empty(QLink front)
{
return fron == NULL;
}
插入
int ADDQ(QLink &front, QLink &rear, int item)
{
QLink p;
if(!(p = (QLink)malloc(sizeof(QNode))))
return 0;
else{
p->data = item;
p->link = NULL;
if(front == NULL)
front = p;
else
rear->link = p;
rear = p;
return 1;
}
}
刪除
int DELQ(QLink &front, QLink &rear, int &item)
{
QLink p;
if(Empty(front, rear))
return 0;
else{
p = front;
front = front->link;
item = p->data;
free(p);
return 1;
}
}