一、栈
定义:一中特殊的线性表,其插入和收纳处均在表的一端进行,是一种运算受限的线 性表。其中,允许插入和删除的一端称之为栈顶,另一端为栈底。
栈的特点——后进先出
栈有两种表示方法,一种是顺序表实现栈,另一种是链式存储实现栈。这里主要介绍链式存储实现栈的数据结构。
a).栈的顺序存储(简介)
即定义一个数组,以数组头为栈底,设一个int top指针指向栈顶,即可完成栈的基本操作。
b)栈的链式存储
1.栈的结构定义——其中,top为栈顶,buttom为栈底
typedef struct node
{
int data;
struct node*next;
}node,*pnode;//define node
typedef struct stack
{
pnode top;
pnode buttom;
}stack,*pstack;//define stack
2.栈的初始化——初始化的时候将栈的栈顶指针指向栈底指针。
pstack CreateStack()
{
pstack st;
st=(pstack)malloc(sizeof(stack));
assert(st);
st->top=st->buttom;
return st;
}//创建栈的函数
3.栈的摧毁
void DestroyStack(pstack st)
{
pnode n;
while(st->top!=st->buttom)
{
n=st->top;
st->top=st->top->next;
free(n);
n=NULL;
}
free(st);
st=NULL;
}//摧毁栈
4.栈的清除
void ClearStack(pstack st)
{
pnode n;
while(st->top!=st->buttom)
{
n=st->top;
st->top=st->top->next;
free(n);
n=NULL;
}
}//清空栈
5.栈的判断为空
void EmptyStack(pstack st)
{
if(st->top==st->buttom||st==NULL)
{
printf("The stack is NULL\n");
}
else
{
printf("The stack is exist!\n");
}
}//判栈空
6.求栈的长度
int LengthStack(pstack st)
{
int l=0;
pnode n;
n=st->top;
while(st->buttom!=n)
{
l++;
n=n->next;
}
// printf("%d\n",l);
return l;
}//判栈长
7.取栈顶元素
int GetTop(pstack st)
{
int d;
if(st->top==st->buttom)
{
printf("The stack is NULL\n");
exit(0);
}
else
{
d=st->top->data;
return d;
}
}//取栈顶元素
8.入栈操作
pnode Push(pstack st,int d)
{
pnode n=(pnode)malloc(sizeof(node));
n->data=d;
n->next=st->top;
st->top=n;
return st->top;//返回入栈后的头结点
}//入栈
9.出栈操作
pnode Pop(pstack st,int*p)
{
pnode n;
if(st->top==st->buttom)
{
printf("The stack is NULL\n");
exit(0);
}
else
{
*p=st->top->data;
n=st->top;
st->top=st->top->next;
free(n);
n=NULL;
return st->top;
}
}//出栈
9.遍历栈
void StackTravers(pstack st)
{
pnode n;
printf("The stack's elem:\n");
n=st->top;
while(n!=st->buttom)
{
printf("%d ",n->data);
n=n->next;
}
printf("\n");
}//遍历栈
3.栈的应用
栈的应用主要有:数制的转换、括号匹配的检验、行编辑程序问题、表达式求解、迷宫的DFS遍历。
其中,栈的表达式求解和迷宫的DFS遍历会在我的其他博客中提到。
二、队列
定义:运算受限的特殊的线性表,表的一端进行插入,表的另一端进行删除。其中,队尾是允许插入的一端,队头是允许删除的一端。
特点:先进先出
其中,队列的基本操作和数据结构类似于栈,这里就不在重复,但提一下其数据结构的代码。
typedef struct QNode
{
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct
{
QueuePtr front;
QueuePtr rear;
} LinkQueue;
队列中设计的问题:
1.队列(以顺序表存储)的假溢出现象:即当元素被插入到数组中下标最大的位置上之后,队列的空间就用尽了,但此时数组的低端还有空闲空间。这时候,则应利用队尾指针和队头指针进行判断,以此来提高存储空间的利用率。
2.可设计循环队列,以提高对空间的利用率。
3.需知道如何判断循环队列中为空,还是为满
这里有两种方法
一:设立一个count参数,记录队列中的数据,当count==MAXSIZE时,表示队列为满。
二:以队尾指针的下一位为队头指针判断队列为满,但此时要牺牲一个存储空间。
队列的应用
1.约瑟夫出圈问题(我的其他博客中有)
n个人排成一圈,从第一个开始报数, 报到 m的人出圈,剩下的人继续开始从1报数,直到所有 的人都出圈为 止
2.舞伴问题
假设在周末舞会上,男士们和女士们进入舞厅 时, 各自排成一队。跳舞开始时,依次从男队和女队的队 头上各出一 人配成舞伴。若两队初始人数不相同,则较长 的那一队中未配对 者等待下一轮舞曲。现要求写算法模拟 上述舞伴配对问题
3.迷宫的最短路劲问题,即BFS遍历迷宫(我的其他博客中有)
本文详细介绍了数据结构中的栈和队列。栈作为一种后进先出的线性表,通过顺序和链式存储实现,常见应用包括括号匹配、表达式求解等。队列则是先进先出的数据结构,涉及队列的假溢出现象、循环队列的设计,应用场景如约瑟夫出圈问题、舞伴问题和BFS迷宫路径寻找。
1497

被折叠的 条评论
为什么被折叠?



