数据结构(二)——栈和队列

本文详细介绍了数据结构中的栈和队列。栈作为一种后进先出的线性表,通过顺序和链式存储实现,常见应用包括括号匹配、表达式求解等。队列则是先进先出的数据结构,涉及队列的假溢出现象、循环队列的设计,应用场景如约瑟夫出圈问题、舞伴问题和BFS迷宫路径寻找。

一、栈
定义:一中特殊的线性表,其插入和收纳处均在表的一端进行,是一种运算受限的线 性表。其中,允许插入和删除的一端称之为栈顶,另一端为栈底。
栈的特点——后进先出
栈有两种表示方法,一种是顺序表实现栈,另一种是链式存储实现栈。这里主要介绍链式存储实现栈的数据结构。
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遍历迷宫(我的其他博客中有)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值