栈
定义
栈:是限定仅在表尾进行插入或者删除操作的线性表、可以概括为后进先出的线性表。
栈顶:线性表允许进行插入和删除操作的那一端。
栈底:固定的、不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。
栈的顺序存储结构
类似于顺序表、插入和删除操作均在表尾。
栈的顺序存储的表示
typedef struct {
Elemtype *base,*top;
int stacksize;
}SqStack;
顺序栈的基本操作
#define MaxSize 50;
type struct{
Elemtype data[MaxSize];
int top;
}SqStack;
初始化
void InitStack(&S){
S.top=-1;
}
栈判空
bool StackEmpty(S){
return S.top==-1;
}
进栈
bool Push(SqStack &S,ElemType x){
if(S.top==MaxSize-1)
return false;
S.data[++S.top]=x;
return true;
}
出栈
bool Pop(SqStack&S,ElemType &x){
if(S.top==-1)
return false;
x=S.data[S.top--]; //先出栈在--
return true;
}
栈顶元素
bool GetTop(SqStack S,ElemType &x)
{
if(S.top==-1)
return false;
x=S.data[S.top];
return true;
//注意: 这里栈顶指针指向的就是栈顶元素、如果栈顶指针初始化为S.top=0,则入栈变为S.data[S.top++],出栈变为x=S.data[--S.top]
栈的链式存储结构
通常用不带头结点的单链表实现、并规定所有操作都在表头进行。
栈的链式存储表示
typedef struct Linknode{
Elemtype data;
struct Linknode *next;
}*LiStack;
链栈的基本操作
入栈
bool Push(LiStack &s,ElemType x)
{
Linknode *p; //申明入栈结点
p=(Linknode)malloc(sizeof(Linknode)); //申请空间
if(!p)
return false;
p->data=x;
p->next=s; //指向栈
s=p; //重新指向栈顶
return true;
出栈
bool Pop(LiStack &s,ElemType &x)
{
Linknode *p;
if(!s)
return false;
p=s;
s=s->next; //栈顶指向下一个栈元素
x=p->data;
free(p);
return true;
}
栈顶元素
bool GetTop(LiStack &s,ElemType &x)
{
if(s)
return false;
x=s->data;
return true;
}
队列
定义
队列:一种操作受限的线性表、只允许在表的一端进行插入、而在表的另一端进行删除。其操作特性是先进先出、故又称先进先出的线性表。
队头:允许删除的一端、又称为队首。
队尾:允许插入的一端。
空队列:不含任何元素的空表。
队列的顺序存储
队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针front和rear分别指向队头元素和队尾元素的位置。
队列的顺序存储表示
#define MaxSize 50
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
//设front指向队头元素、rear指向对尾元素的下一个位置、则
//队空条件为:Q.front==Q.rear==0;
//入队操作:队不满时,先送值到队尾元素、再将队尾指针加1;
//出队操作:队不空时,先去队头元素值,再将队头指针加1;
//能否用Q.rear==MaxSize判断队满?不能、因此引出循环队列
循环队列
将顺序队列想象成一个环状的存储空间、即把存储队列元素的表从逻辑上看成一个环、称为循环队列。当队首指针Q.front==MaxSize-1,在前进一个位置就自动到0,则
- 队空条件:Q.front==Q.rear;
- 队满条件:(Q.rear+1)%MaxSize==Q.front (队列少用一个元素时);
- 进队操作:Q.rear=(Q.rear+1)%MaxSize;
- 出队操作:Q.front=(Q.front+1)%MaxSize;
- 队列长度:(Q.rear+MaxSize-Q.front)%MaxSize;
初始化
void InitQueue(&Q){
Q.front=Q.rear=0;
}
入队操作
bool EnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front)
return false; //队列满
Q.data[Q.rear]=x; //数组从0开始
Q.rear=(Q.rear+1)%MaxSize;
return true;
}
出队操作
bool DeQueue(SqQueue &Q,ElemType &x){
if(Q.front==Q.rear)
return false;
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
队列中的 元素个数
int QueueLength(SqQueue Q){
return (Q.rear-Q.front+MaxSize)%MaxSize;
}
队列的链式存储结构
队列的链式实现称为链队列,即一个同时带有队头指针和对尾指针的单链表,头指针指向队头结点,尾指针指向队尾结点(单链表的最后一个结点)。
队列的链式存储
typedef struct QNode{
QElemtype data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr *front,*rear;
}LinkQueue;
初始化
Status InitQueue(LinkQueue &Q){
//构造一个空队列
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.front->next=null;
return OK;
队空
void isEmpty(LinkQueue &Q){
return Q.front==Q.rear);
}
入队
Status EnQueue(LinkQueue &Q,QElemType e){
//插入元素e为Q的新的队尾元素
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 Deque(LinkQueue &Q,QElemType &e){
//若队列不空、则删除Q的队头元素,用e返回其值,并返回OK;
//否则返回ERROR
if(Q.front==Q.rear) return ERROR;
p=Q.front->next; //头结点front指向的第一个结点
e=p->data;
Q.front->next=p->next; //队列往下一个进1
if(Q.rear==p) Q.rear=Q.front;
free(q);
return OK;
以上就是对栈和队列的简单梳理