栈
栈是一个特殊的线性表,只能在一端操作;
栈顶(top):允许操作 的一端;
栈底(bottom):不允许操作的一端
性质:先进后出
栈的常见操作:
创建栈
销毁栈
清空栈
进栈
出栈
获取栈顶元素
获取栈的长度
1.栈:是限定仅在表尾进行插入和删除操作的线性表;又称后进先出的线性表。LIFO结构。
栈顶top:允许插入和删除的一端;
栈底bottom:另外一端;
2. 空栈:不含任何数据元素的栈;top=-1;
3. 栈的操作:
进栈,压栈,入栈:栈的插入操作;
出栈,弹栈:栈的删除操作;
栈中有一个元素时,top=0;
4. 栈的抽象数据类型:
插入和删除:push,pop 同线性表。 元素具有相同的类型,相邻元素具有前驱和后继的的关系。
操作:
a.初始化操作,建立空栈S;
b. 若栈存在,就销毁它;
c.将栈清空;
d.判断栈是否空:空返回true,否则返回false;
e. 若栈存在非空,用e返回s的栈顶元素;
f. 若栈S存在,插入新元素e到栈s成为栈顶元素;
g.删除栈s栈顶元素,并用e返回其值;
h.返回栈s的元素个数。
5. 若存储栈的长度为StackSize,则栈顶位置top必须小于StackSize。
若栈存在一个元素,top=0;
空栈的条件:top=-1;
栈的结构:
typedef struct sqStack
{
int data[MAXSIZE];
int top;
}STACK;
6.进栈操作:
int Push(STACK *S, int e)
{
if(S->top == MAXSIZE -1)
return error;
S->top++;
S->data[S->top]=e;
return OK;
}
7. 出栈操作:
int Pop(STACK *S, int *e)
{
if(S->top == -1)
return ERROR;
*e=S->data[S->top];
S->top--;
return OK;
}
8.栈的链式存储结构
栈的链式存储结构,简称为链栈;
栈顶放在单链表的头部;
链栈是不需要头结点的。
链栈不存在栈满的情况。
进栈出栈
1.进栈操作:元素值为e的新节点s,top为栈顶指针;
int Push(LinkStack *S, int e)
{
LinkStackPtr p= (LinkStackPtr) malloc (sizeof(StackNode));
p->data=e;
p->next=S->top;
S->top=p;
S->count++;
return OK;
}
2.栈的链式出栈:
pop操作:用变量p用来存储要删除的栈顶结点,将栈顶指针向下移动一位,最后释放p即可。
int Pop(LinkStack *S, int *e)
{
LinkStackPtr p;
if(StackEmpty(*S))
return ERROR;
*e=S->top->data;
p=S->top;
S->top=S->top->next;
free(p);
S->count--;
reuturn OK;
}
队列
队列是特殊的线性表;
队列仅在线性表两端进行操作;
队头(Front):取出数据的一端;
队尾(Rear):放入数据的一端;
性质:先进先出。
常见队列的操作:
创建队列
销毁队列
清空队列
进队列
出队列
获取队头元素
获取队列长度
a.队列的抽象数据模型:
1)初始化操作,建立一个空队列Q;
2)若队列存在,则销毁它;
3)将队列清空
4)若队列Q为空,返回true,否则返回false;
5)若队列Q存在且非空,用e返回队列Q的队头元素;
6)若队列Q存在,插入新元素e到队列Q中,并成功称为队尾元素;
7)删除队列Q中队头元素,并用e返回其值;
8)返回队列Q的元素个数;
b.循环队列:
1.队列顺序存储的不足:
避免出现只有一个元素时,队头和队尾的重合处理麻烦,
引入front指向队头元素,rear指向队尾元素的下一个位置;
front=rear时,队列不是还剩一个元素,而是空队列;
2.循环队列定义:
把头尾相接的顺序存储结构称为循环队列;
判断队列满的条件:
(rear+1)%QueueSize==front;
通用的计算队列长度公式为:
(rear-front+QueueSize)%QueueSize;
typedef struct
{
int data[MAXSIZE];
int front;
int rear;
}SqQueue;
3.初始化一个空队列Q:
int InitQueue(SqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}
4.求队列长度:
int QueueLength(SqQueue Q)
{
return (Q.rear -Q.front+MAXSIZE)%MAXSIZE;
}
5 . 循环队列的入队列:
int EnQueue(SqQueue *Q, int e)
{
if((Q->rear+1)%MAXSIZE ==Q->front)
return ERROR;
Q->data[Q->rear] = e;
Q->rear=(Q->rear+1)%MAXSIZE;
return OK;
}
6.循环队列的出队列:
int DeQueue(SqQueue *Q, int *e)
{
if(Q->rear==Q->front)
return ERROR;
*e=Q->data[Q->front];
Q->front=(Q->front+1)%MAXSIZE;
return OK;
}