C语言数据结构(大话数据结构——笔记2)第四章:栈与队列
Posted Dontla
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言数据结构(大话数据结构——笔记2)第四章:栈与队列相关的知识,希望对你有一定的参考价值。
文章目录
- 第四章:栈与队列(115)
- 栈顶与栈底,空栈,后进先出 Last in first out(LIFO结构)(117)
- 进栈、压栈、入栈:栈的插入操作;出栈、弹栈:栈的删除操作(118)
- push、pop,压栈和弹栈(进栈和出栈 )(119)
- 栈的顺序存储结构:顺序栈(数组实现)(120)
- 两栈共享空间(122)
- 栈的链式存储结构(链栈)(125)
- 顺序栈和链栈的优缺点:(128)
- 栈的作用:简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决的问题核心。(128)
- 栈的应用:递归(128)
- 队列的定义(139)
- 队列的抽象数据类型(140)
- 循环队列(顺序存储结构)(140)
- 队列的链式存储结构及实现(其实就是线性表的单链表修改版,只能尾进头出)(链队列)(145)
- 栈与队列总结(149)
- 本章配套代码
第四章:栈与队列(115)
栈顶与栈底,空栈,后进先出 Last in first out(LIFO结构)(117)
进栈、压栈、入栈:栈的插入操作;出栈、弹栈:栈的删除操作(118)
push、pop,压栈和弹栈(进栈和出栈 )(119)
栈的顺序存储结构:顺序栈(数组实现)(120)
两栈共享空间(122)
最好是相同的数据类型共享(124)
栈的链式存储结构(链栈)(125)
链栈不需要头结点(创建一个栈链结构,结构中包含指向栈顶top的指针和结点数量)
栈的链式存储结构——进栈push操作:(126)
栈的链式存储结构——出栈pop操作:(127)
顺序栈和链栈的优缺点:(128)
栈的作用:简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决的问题核心。(128)
栈的应用:递归(128)
斐波那契数列实现(129)
斐波那契数列:前面两项之和,构成了后一项
传统迭代方法
递归算法
递归函数的定义(131)
一个直接调用自己,或通过一系列的调用语句间接地调用自己的函数,称为递归函数
递归与迭代的区别(132)
栈在递归操作中的作用(132)
栈的应用——四则运算表达式求值(132)
后缀(逆波兰)(reverse polish notation, RPN)表示法(133)
后缀表达式(133)
中缀表达式(标准四则运算表达式)转后缀表达式(136)
队列的定义(139)
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表
先进先出(first in first out, FIFO),允许插入的一端称为队尾,允许删除的一端称为队头
队列的抽象数据类型(140)
循环队列(顺序存储结构)(140)
队列顺序存储的缺点(140)
出队时间复杂度高(O(n))
front与rear指针(141)
假溢出的概念(142)
不循环所存在的问题:后面满了,但前面空着,不会把元素加到前面
循环队列定义(142)
头尾相接的顺序存储结构
如何判断循环队列是空还是满?(143)
假设队列的最大尺寸是QueueSize,则队列满的条件是(rear + 1)% QueueSize == front
,%为取模符号
通用计算队列长度公式(144)
(rear - front + QueueSize)% QueueSize
循环队列顺序存储结构代码(144)
顺序存储结构循环队列缺点:可能会溢出(145)
队列的链式存储结构及实现(其实就是线性表的单链表修改版,只能尾进头出)(链队列)(145)
队头指针指向队列头结点,队尾指针指向终端结点
队列的链式存储结构——入队操作
入队操作:在链表尾部插入结点
队列的链式存储结构——出队操作
(顺序存储结构)循环队列与链队列的对比(链队列每次malloc申请和释放结点也会存在一定的时间开销)(148)
栈与队列总结(149)
本章配套代码
顺序栈
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */
/* 顺序栈结构 */
typedef struct
{
SElemType data[MAXSIZE];
int top; /* 用于栈顶指针 */
}SqStack;
Status visit(SElemType c)
{
printf("%d ",c);
return OK;
}
/* 构造一个空栈S */
Status InitStack(SqStack *S)
{
/* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
S->top=-1;
return OK;
}
/* 把S置为空栈 */
Status ClearStack(SqStack *S)
{
S->top=-1;
return OK;
}
/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
Status StackEmpty(SqStack S)
{
if (S.top==-1)
return TRUE;
else
return FALSE;
}
/* 返回S的元素个数,即栈的长度 */
int StackLength(SqStack S)
{
return S.top+1;
}
/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
Status GetTop(SqStack S,SElemType *e)
{
if (S.top==-1)
return ERROR;
else
*e=S.data[S.top];
return OK;
}
/* 插入元素e为新的栈顶元素 */
Status Push(SqStack *S,SElemType e)
{
if(S->top == MAXSIZE -1) /* 栈满 */
{
return ERROR;
}
S->top++; /* 栈顶指针增加一 */
S->data[S->top]=e; /* 将新插入元素赋值给栈顶空间 */
return OK;
}
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(SqStack *S,SElemType *e)
{
if(S->top==-1)
return ERROR;
*e=S->data[S->top]; /* 将要删除的栈顶元素赋值给e */
S->top--; /* 栈顶指针减一 */
return OK;
}
/* 从栈底到栈顶依次对栈中每个元素显示 */
Status StackTraverse(SqStack S)
{
int i;
i=0;
while(i<=S.top)
{
visit(S.data[i++]);
}
printf("\\n");
return OK;
}
int main()
{
int j;
SqStack s;
int e;
if(InitStack(&s)==OK)
for(j=1;j<=10;j++)
Push(&s,j);
printf("栈中元素依次为:");
StackTraverse(s);
Pop(&s,&e);
printf("弹出的栈顶元素 e=%d\\n",e);
printf("栈空否:%d(1:空 0:否)\\n",StackEmpty(s));
GetTop(s,&e);
printf("栈顶元素 e=%d 栈的长度为%d\\n",e,StackLength(s));
ClearStack(&s);
printf("清空栈后,栈空否:%d(1:空 0:否)\\n",StackEmpty(s));
return 0;
}
两栈共享空间
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */
/* 两栈共享空间结构 */
typedef struct
{
SElemType data[MAXSIZE];
int top1; /* 栈1栈顶指针 */
int top2; /* 栈2栈顶指针 */
}SqDoubleStack;
Status visit(SElemType c)
{
printf("%d ",c);
return OK;
}
/* 构造一个空栈S */
Status InitStack(SqDoubleStack *S)
{
S->top1=-1;
S->top2=MAXSIZE;
return OK;
}
/* 把S置为空栈 */
Status ClearStack(SqDoubleStack *S)
{
S->top1=-1;
S->top2=MAXSIZE;
return OK;
}
/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
Status StackEmpty(SqDoubleStack S)
{
if (S.top1==-1 && S.top2==MAXSIZE)
return TRUE;
else
return FALSE;
}
/* 返回S的元素个数,即栈的长度 */
int StackLength(SqDoubleStack S)
{
return (S.top1+1)+(MAXSIZE-S.top2);
}
/* 插入元素e为新的栈顶元素 */
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
if (S->top1+1==S->top2) /* 栈已满,不能再push新元素了 */
return ERROR;
if (stackNumber==1) /* 栈1有元素进栈 */
S->data[++S->top1]=e; /* 若是栈1则先top1+1后给数组元素赋值。 */
else if (stackNumber==2) /* 栈2有元素进栈 */
S->data[--S->top2]=e; /* 若是栈2则先top2-1后给数组元素赋值。 */
return OK;
}
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{
if (stackNumber==1)
{
if (S->top1==-1)
return ERROR; /* 说明栈1已经是空栈,溢出 */
*e=S->data[S->top1--]; /* 将栈1的栈顶元素出栈 */
}
else if (stackNumber==2)
{
if (S->top2==MAXSIZE)
return ERROR; /* 说明栈2已经是空栈,溢出 */
*e=S->data[S->top2++]; /* 将栈2的栈顶元素出栈 */
}
return OK;
}
Status StackTraverse(SqDoubleStack S)
{
int i;
i=0;
while(i<=S.top1)
{
visit(S.data[i++]);
}
i=S.top2;
while(i<MAXSIZE)
{
visit(S.data[i++]);
}
printf("\\n");
return OK;
}
int main()
{
int j;
SqDoubleStack s;
int e;
if(InitStack(&s)==OK)
{
for(j=1;j<=5;j++)
Push(&s,j,1);
for(j=MAXSIZE;j>=MAXSIZE-2;j--)
Push(&s,j,2);
}
printf("栈中元素依次为:");
StackTraverse(s);
printf("当前栈中元素有:%d \\n",StackLength(s));
Pop(&s,&e,2);
printf("弹出的栈顶元素 e=%d\\n",e);
printf("栈空否:%d(1:空 0:否)\\n",StackEmpty(s));
for(j=6;j<=MAXSIZE-2;j++)
Push(&s,j,1);
printf("栈中元素依次为:");
StackTraverse(s);
printf("栈满否:%d(1:否 0:满)\\n",Push(&s,100,1));
ClearStack(&s);
printf("清空栈后,栈空否:%d(1:空 0:否)\\n",StackEmpty(s));
return 0;
}
链栈
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */
/* 链栈结构 */
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct
{
LinkStackPtr top;
int count;
}LinkStack;
Status visit(SElemType c)
{
printf("%d ",c);
return OK;
}
/* 构造一个空栈S */
Status InitStack(LinkStack *S)
{
S->top = (LinkStackPtr)malloc(sizeof(StackNode));
if(!S->top)
return ERROR;
S->top=NULL;
S->count=0;
return OK;
}
/* 把S置为空栈 */
Status ClearStack(LinkStack *S)
{
LinkStackPtr p,q;
p=S->top;
while(p)
{
q=p;
p=p->next;
free(q);
}
S->count=0;
return OK;
}
/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
Status StackEmpty(LinkStack S)
{
if (S.count==0)
return TRUE;
else
return FALSE;
}
/* 返回S的元素个数,即栈的长度 */
int StackLength(LinkStack S)
{
return S.count;
}
/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
Status GetTop(LinkStack S,SElemType *e)
{
if (S.top==NULL)
return ERROR;
else
*e=S.top->data;
return OK;
}
/* 插入元素e为新的栈顶元素 */
Status Push(LinkStack *S,SElemType e)
{
LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
s->data=e;
s->next=S->top; /* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
S->top=s; /* 将新的结点s赋值给栈顶指针,见图中② */
S->count++;
retu以上是关于C语言数据结构(大话数据结构——笔记2)第四章:栈与队列的主要内容,如果未能解决你的问题,请参考以下文章
C语言数据结构(大话数据结构——笔记1)数据结构绪论算法线性表