数值转换、表达式求值
括号匹配、八皇后问题
行编译程序、函数调用
迷宫问题、递归调用的实现
栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表
栈的相关概念
1.定义:限定只能在表的一端进行插入和删除运算的线性表(只能在栈顶操作)
2.逻辑结构:与线性表相同,仍为一对一关系。
3.存储结构:用顺序栈戟链栈存储均可,但以顺序栈更常见
4.运算规则:只能在栈顶运算,且访问结点时依照进先出(LIFO)的原则
5.实现方式:关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同
6.插入和删除都在一端进行,进行插入和删除操作的一端叫栈顶,另一端叫栈底
栈的特点
后进先出
栈与一般线性表用什么不同
队列的应用
队列的定义
插入在线性表的一端(表尾),删除在表的另一端(表头)
队列的相关概念
1.定义:只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表(头删尾插)
2.逻辑结构:与线性表相同,仍为一对一关系
3.存储结构:顺序队或链队,以循环顺序队列更常见
4.运算规则:只能在队首和队尾运算,且访问结点时依照先进先出(FIFO)的原则
5.实现方式:关键是掌握入队和出队操作,具体实现依顺序队或链队的不同而不同
栈的特点
先进先出
注:上溢是一种错误,使问题的处理无法进行;而溢般认为是
一种结束条件,即问题处理结束。
#define MAXSIZE 100
typedef struct{
SElemType *base;// 栈底指针
SElemType *top;// 栈顶指针
int stacksize;// 栈的最大个数
}SqStack;
Status InitStack(SqStack &S){
S.base=new SElemType[MAXSIZE];// 初始化空间
if(!S.base)exit(OVERFLOW);
S.top=S.base;// 建立空栈
S.stacksize=MAXSIZE;
return OK;
}
Status StackEmpty(SqStack S){
if(S.top==S.base)return TRUE;
else return FALSE;
}
int StackLength(SqStack S){
return S.top-S.base;
}
Status ClearStack(SqStack S){
if(S.base)S.top=S.base;
return OK;
}
Status DestroyStack(SqStack &S){
if(S.base) {
delete S.base;
S.stacksize = 0;
S.base=S.top=NULL;
}
return OK;
}
Status Push(SqStack &S,SElemType e){
if(S.top-S.base==S.MAXSIZE)return ERROR;// 判断是否栈满
*S.top++=e;//加入新元素
return OK;
}
Status Pop(SqStack &S,SElemType &e){
if(S.top==S.base)return ERROR;//判断栈是否为空
e=*--S.top;//取栈顶元素
return OK;
}
typedef struct StackNode{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
LinkStack S;
注:
1.链表的头指针就是栈顶
2.不需要头结点
3.基本不存在栈满的情况
4.空栈相当于头指针指向空
5.插入和删除仅在栈顶处执
行
链栈的初始化
void InitStack(LinkStack &S){
S=NULL;
return OK;
}
Status StackEmpty(LinkStack S){
if(S==NULL)return TRUE;
else return FALSE;
}
Status Push(LinkStack &S,SElemType e){
p=new StackNode;//生成新结点
p->data=S;
p->next=S;
S=p;//栈顶
return OK;
}
Status Pop(LinkStack &S,SElemType &e){
if(S==NULL)return ERROR;
e=S->data;//取出栈顶元素
p=S;//
S=S->next;//更新栈顶
delete p;
return OK;
}
SElemType GetTop(LinkStack S){
if(S!=NULL) return S->data;
}
递归的定义
以下三种情况常常用到递归方法
递归问题-用分治法求解
分治法求解递归问题算法的一般形式:
void p(参数表){
if(递归结束条件) 可直接求解; ---基本项
else p(较小的参数); ---归纳项
}
eg:
long Fact(long n){
if(n==0)return 1;//基本项
else return n*Fact(n-1);//归纳项
}
递归->非递归实现
方法1:尾递归、单向递归→循环结构
方法2:自用栈模拟系统的运行时栈
尾递归->循环结构
#define MAXQSIZE 100
typedef struct {
QElemType *base;//初始化动态存储空间
int front,rear;//对头和对尾
}SqQueue;
队列的操作
初始化:front=rear=0;
入队:base[rear]=x,rear++;
出队:x=base[front],front++;
队空标志:front==rear;
解决假溢出的方法–引入循环队列
取余实现
循环队列队满对空判断
1.另设一个标志以区别对空队满
2.另设一个变量,记录元素的个数
3.少用一个元素***
少用一个元素空间判断队空队满
队满:(rear+1)%maxsize == front
队空:rear == front
队列初始化
Status InitQueue(SqQueue &Q){
Q.base=new QElemType[MAXQSIZE];//分配数组空间
if(!Q.base)exit(OVERFLOW);//分配失败
Q.front = Q.rear = 0;
return 0;
}
int QueueLength(SqQueue Q){
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
Status EnQueue(SqQueue &Q,QElemType e){
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q,QElemType &e){
if(Q.front==Q.rear)return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
SElemType GetHead(SqQueue Q){
if(Q.front!=Q.rear)
return Q.base[Q.front];
}
#define MAXQSIZE 100
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
链队列的指针变化
尾插头删
链队列的初始化
Status InitQueue(LineQueue &Q){
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
Status DestroyQueue(LinkQueue &Q){
LinkQueue p;
while(Q.front){
p=Q.front->next;free(Q.front);Q.front=p;
}
return OK;
}
Status EnQueue(LinkQueue &Q,QElemType e){
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)exit(OVERFLOW);
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
p=Q.front->next;
e=p->next;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
delete p;
return OK;
}
Status GetHead(LinkQueue Q,QElemType &e){
if(Q.front==Q.rear)return ERROR;
e=Q.front->next->data;
return OK;
}