北航软件工程专业考研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;
}
}