目录
第三章 栈、队列和数组
3.1 栈
3.1.1 栈的基本概念
定义
出栈顺序计算公式:
知识回顾
3.1.2 栈的顺序存储实现
定义
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //静态数组存放栈中的元素
int top; //栈顶指针
}SqStack;
初始化
//初始化栈
void InitStack(SqStack &S){
S.top = -1; //初始化栈顶指针
}
判断栈空
//判断栈空
bool StackEmpty(SqStack S){
if(S.top==-1)
return true; //栈空
else
return false; //栈不空
}
入栈
bool Push(SqStack &S,ElemType x){
if(S.top==MaxSize-1) //栈满,报错
return false;
S.top = S.top + 1; //指针+1
S.data[S.top] = x; //新元素入栈
//上面两行代码等价于:
//S.data[++S.top] = x;
return true;
}
出栈操作
bool Pop(SqStack &S,ElemType &x){
if(S.top==-1) //栈满,报错
return false;
x = S.data[S.top] //栈顶元素先出栈
S.top = S.top - 1; //指针再减1
//以上两行代码等价于:
//x = S.data[S.top--];
return true;
}
读栈顶元素
bool GetTop(SqStack S,ElemType &x){
if(S.top==-1) //栈空,报错
return false;
x = S.data[S.top]; //x记录栈顶元素
return true;
}
新方式
栈顶元素可以初始值为0
判断栈空:S.top0
判断栈满:topMaxSize
共享栈
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //静态数组存放栈中元素
int topo; //0号栈线顶指针
int top1; //1号栈线顶指针
}ShStack;
//初始化栈
void InitStack(ShStack &S){
S.top0 = -1; //初始化栈顶指针
S.top1 = MaxSize;
}
//栈满的条件:top0 + 1 = top1;
知识总结
3.1.3 栈的链式存储实现
头插法建立单链表
//后插操作,在p结点之后插入元素e
bool InsertNextNode(LNode *p,ElemType e){
if(p==NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if(s==NULL) //内存分配失败
return false;
s->data = e; //用结点s保存数据元素e
s->next = p->next;
p->next = s; //将结点s链接到p之后
return true;
}
3.2.1 队列的基本概念
队列的定义
队列(Queue)
是只允许在一端进行插入,在另一端删除的线性表
队列的特点:先进先出
知识回顾
3.2.2 队列的顺序实现
定义
#define MaxSize 10 //定义队列中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //用静态数组存放队列元素
int front,rear; //队头指针和队尾指针
}sqQueue;
初始化
//初始化队列
void InitQueue(SqQueue &Q){
//初始时 队头、队尾指针指向0
Q.rear = Q.front = 0;
}
判断队列是否为空
//判断队列是否为空
bool QueueEmpty(SqQueue Q){
if(Q.rear == Q.front) //队空条件
return true;
else
return false;
}
入队
//入队
bool EnQueue(SqQueue &Q,ElemType x){
if(队列已满)
return false; //队慢则报错
Q.data[Q.rear] = x; //新元素插入队尾
Q.rear = (Q.rear+1)%MAxSize; //队尾指针加1取模
return true;
}
循环队列-入队
//入队
boolEnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front) //判断队满
return false;
Q.data[Q.rear] = x; //新元素插入队尾
Q.rear=(Q.rear+1)%MaxSize; //队尾指针加1取模
return true;
}
循环队列-出队
//出队(删除一个队头元素,并用x返回)
boolDeQueue(SqQueue &Q,ElemType &x){
if(Q.rear==Q.front)
return false; //队空则报错
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
队列元素个数:
(rear+MaxSize-front)%MaxSize
队列已满的条件:
队尾指针的再下一个位置是队头,即(Q.rear+1)%MaxSize==Q.front
队空条件:
Q.rear == Q.front
知识回顾
3.2.3 队列的链式实现
定义
typedef struct LinkNode{ //链式队列结点
ElemTypedata;
struct LinkNode *next;
}LinkNode;
typedef struct{ //链式队列
LinkNode *front,*rear; //队列的队头和队尾指针
}LinkQueue;
初始化(带头节点)
//初始化队列
void InitQueue(LinkQueue &Q){
//初始化 front、rear都指向头结点
Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
Q.front->next=NULL;
}
判断队列是否为空
//判断队列是否为空
bool IsEmpty(LinkQueueQ){
if(Q.front==Q.rear)
return true;
else
return false;
}
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q){
//初始时front、rear都指向NULL
Q.front=NULL;
Q.rear=NULL;
}
判断队列是否为空(不带头结点)
//判断队列是否为空(不带头结点)
bool IsEmpty(LinkQueue Q){
if(Q.front==NULL)
return true;
else
return false;