数据结构---表

本文探讨了数据结构中的表,包括链表的优缺点,以及不带头结点和带头结点链表的操作。重点介绍了栈和队列这两种功能受限的表结构,阐述了它们的特性如先进后出(FIFO)和先进先出(FIFO),并列举了栈和队列在函数调用、生产者消费者模型等场景的应用。同时,提及了汉诺塔问题和环形队列的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

顺序表:array
        数据项:
            存储元素的内存首地址
            表的容量
            元素的数量

注意:
1、不要越界
2、时刻保持元素的连续性
优点:支持随机访问、修改、访问、排序的效率比较高,大块的连续内存不容易产生内存碎片
缺点:堆内存要求比较高(内存连续),插入、删除元素时不方便、效率低

链式表:list
        节点的数据项:
            数据域:可以是若干个各种类型的数据项
            指针域:指向下一个节点

不带头结点:第一个节点的数据域存储的是有效的数据
添加、删除时有可能会改变第一个节点的指针指向,参数需要传递二级指针,而且删除第一个节点时,还需要额外处理。

带头结点的:第一个节点不使用,仅仅只是用来指向第一个数据域有效的节点
注意:操作需要从第二个节点(也就是第一个有效数据节点)开始
注意:下标从第一个有效数据节点开始

功能受限的表:

栈:只有一个进出的出入口的表结构,先进后出,FILO

顺序栈:
    数据项:
        存储元素的内存首地址
        栈的容量
        栈顶位置
    运算:
        创建、销毁、入栈、出栈、栈满、栈空、栈顶

注意:
栈顶指向顶部的第一个数据,称为满增栈
栈顶指向接下去要入栈的位置,称为空增栈
满减栈、空减栈

链式栈:
    数据域:
        栈顶
        节点数量
    运算:
       创建、销毁、入栈、出栈、栈空、栈顶

栈的应用:
1、函数的调用(栈内存)
2、生产者和消费者模型(栈作为仓库)
3、表达式的解析
栈的常见笔试面视题:
某个序列是入栈的顺序,判断哪个序列为合理的出栈顺序
1 2 3 4 5
3 1 2 4 5 No
1 2 3 4 5 yes

        练习:实现一个函数,判断序列b是不是序列a的出栈顺序
        bool is_popstack(int* a,int* b,int len)
        {
            //  创建一个栈
            //  按照a的顺序一个一个入栈
                //  按照b的顺序出栈
            //  最后判断栈是否为空
        }
        问题:两个栈如何使用能够让空间利用率最大化?

拓展:Hanoi塔总的移动次数:2^n-1
队列:
一个端口进,另一个端口出,先进先出 FIFO

顺序队列:
      数据项:
          存储元素的内存首地址
          容量
          队头
          队尾    接下去要入队的位置
      运算:
          创建、销毁、入队、出队、队空、队满、队头、队尾、元素个数

注意:
顺序队列是由一维数组+队头位置front+队尾位置rear组成,入队时rear+1,出队时front+1,为了能够让队列反复使用,我们要把一维数组想象成一个环,因此rear、front加1后要用队列的容量求余
rear = (rear+1)%cal;
front = (front+1)%cal;

        如何判断队空:  front == rear
        如何判断队满:  front == (rear+1)%cal
            1、代价是空一个位置不能使用(常考)
            2、添加一个数据项标记队列是空或者满(元素个数)
        如何计算元素的数量:
            (rear-front+cal)%cal
链式队列:
       由若干个节点组成的队列
       数据项:
           队头指针
           队尾指针
           节点数量

队列的应用:
1、消息队列
2、树的层序遍历
3、图的广度优先遍历
4、封装线程池、数据池

    常见的笔试面试题:
        使用两个栈来模拟一个队列的功能
            从栈1到栈2 必须一个不留地入栈
            如果栈2不空,栈1一定不能入栈2

封装链表:

1、单链表
   原因:尾添加的效率低、非法下标判断也很低
   节点:
       数据域
       指针域
   链表数据项:
       头指针
       尾指针
       节点数量
2、静态链表
   节点:
       数据域
       游标
   静态链表的节点存储在连续的内存中,通过游标来访问下一个节点
   这种链表在插入删除时只需要修改游标的值,而不用重新申请、释放内存内存从而达到链式表结构效果
   这样做牺牲了随机访问的功能,主要是提供给没有指针的编程语言实现单链表的一种方法
3、循环链表
   链表的最后一个节点的next不再指向NULL,而是指向头节点,这种链表叫做单向循环链表,简称循环链表,它的好处是可以通过任意节点遍历整个链表
4、双向链表
   节点:
       前驱指针
       数据域
       后继指针
   链表数据项:
       头结点
       节点数量
   双向链表的特点:
       1、从任意节点都可以遍历整个链表
       2、删除、增加就不需要定位待操作节点的上一个
       3、如果知道节点数量,删除已知位置节点,可以选择从前到后或者从后到前进行遍历,从而提高链表的操作效率
5、Linux内核链表
   既然链表不能包含万物,那就让万物包含链表
6、通用链表
   节点:
       指针域
       void* ptr;
   链表数据项:
       头节点指针
       节点数量
   运算:
       常规功能+回调函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LJIEIJL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值