zoukankan      html  css  js  c++  java
  • 数据结构学习笔记——线性表

    数据结构+算法=程序

    线性表的定义:具有相同特性的数据元素的一个有限序列。该序列中所含元素的个数叫做线性表长度。
    定义:L=(a1,a2,a3....an)
    其中为a1表头元素,为an表尾元素
    线性表的顺序存储结构
    其直接将线性表的逻辑结构映射到存储结构上
    ----------------------------------------
    例:两线性表合并算法


    线性表的顺序存储结构----顺序表


    线性表的顺序存储类型可描述如下
    1 #define MAXSIZE 50
    2 typedef struct
    3 {
    4    ElemType date[MAXSIZE];
    5    int length;
    6 }SqList;

    常用基本运算集合
          初始化
          创建
          销毁
          是否为空
          求线性表的长度
          输出线性表
          求线性表中某个元素的值
          按元素值查找
          插入运算(一般是前插)

    顺序表位序从1开始,因此要注意将逻辑位序转化为物理位序

    线性表插入、删除算法时间复杂度为O(n) [注:一般实现]
    ----------------------------------------------------------------------------------------------------------------
    例:有一个顺序表A。设计一个算法,删除所有元素值在[x,y]之间的所有元素,要求算法时间复杂度为O(n),空间复杂度为O(1)
    实现:以A表为基础重新构建一个表。

    例:有一个顺序表L,假设元素类型ElemType为整型,并且所有元素均不相等。设计一个算法,以第一个元素为分界线,将所有小于它的元素移到该元素前面,将所有大于它的元素移到该元素的后面。
    实现1:从两边向中间交替查找不满要求的元素进行交换
    实现2:保留第一个元素的值,然后从右边前左边查到不满要求的元素,并将其设置到第一个元素位置 ... ...(变化基准位置(原来第一个元素的位置),从而将缺省出的基准位用于存放找到的数值)


    线性表的顺序存储结构----链表


    单链表
    对于带头节点的单链表而言
    插入结点:s->next = p->next;
    (插入S,先找到前一个节点p)
                   p->next = s;

    删除结点: p->next = p->next->next;(先找到前一个节点p)
    --------------------------------------------------------------
    例:有一个带头结点的单链表L={a1,b1,a2,b2,a3,b3,...,an,bn},设计一个算法将其拆分成两个带头结点的单链表L1和L2,L1={a1,a2,a3...an},L2={bn,bn-1,...b1}.要求L1使用L的头结点
    注:链表的插入分头插和尾插
    例:有一个带头结点的单链表L,设计一个算法使其元素递增有序。
    问:带头结点的单链表与不带头结点的单链表有何区别?
    答:带头结点单链表可以在头节点中加入一些附加信息,并且有利于实现各种运算(删除和插入)。


    双链表
    双链表的创建与单链表相似,只不过每个结点多了个PRIOR指针域
    双链表亦可分头插和尾插
    特点(对称性):
    p->next->prior = p;
    p->prior->next = p;
    ------------------------------------------------------------------
    例:写一个算法实现双链表倒置
    例:写一个算法实现对双链表进行排序

    循环链表
    分为带头结点的循环单链表和循环双链表。
    其判断结尾条件是:p->next == L(头结点)
    因此头结点也连在整个循环链表中
    针对于其初始化:
    L->prior = L;
    L->next  = L;
    一般为解决特殊问题
    还存在不带头结点的循环单链表和循环双链表(如约瑟夫环)
    --------------------------------------------------------------------------------
    例:有一个带头结点的循环双链表L,设计一个算法删除第一个data值域为X的结点。

    静态链表
    静态
    链表是借助一维数组来描述链表。数组中的一个分量表示一个结点,同时使用游标(cur)代替指针以指示结点在数组中的相对位置(游标为-1时表示相对应的结点为空).数组中的0分量可以看成头结点,其指针域指示静态链表的第一个结点,并将最后一个元素的指针域0构成循环结构
    这种存储结构需预先分配一个较大空间,但是在进行线性表插入和删除操作时不需移动元素,仅需要修改“指针”,因此仍然具有链式存储结构的主要优点。
    一般地, 静态链表的存储类型如下
    #define MAXSIZE 100
    typedef 
    struct
    {
       ElemType data; 
    //数据域
       int next;      //游标域,指示下一个元素在数组中的位置
    }StaticList[MaxSize];
    对于静态链表的初始化,一定要将其它没有元素的结点的.next设为-1,并将下标为[0].next设为0
    对于静态链表可视为一个带头节点的循环链表,_StaticList[0]为其头结点,对于插入操作一般都先查找到前一个结点(前插),另对于新的插入项一定要存在下.next为-1的位置上。
    另对于删除时要考虑链表是否为空表,对于插入要考虑是否表满

    同样静态也有不带头节点的,类似于不带头节点的循环链表
    同样可以构造类似于循环双链表的静态链表  
    等等总之灵活多样但一般不存在单链表式的静态链表

    总结:单链表以尾结点以NULL结尾,而循环链表尾结点指向头结点(如:静态链表)
             因此初始化时,单链表头结点next指向NULL,而循环链表头结点next和prior指向自己


    疑问事项


    线性表中的遍历循环都是用的while,为什么不用for呢?(也许是因为方便,但我就不爱用while,所以难免感到不适)
    (还请大家帮解答一下
  • 相关阅读:
    Socket通信
    浏览器调用打印机
    python dict操作
    python list操作
    python 模块Example链接
    python random模块
    python configparser模块
    python unittest模块
    python timeit模块
    python datetime模块
  • 原文地址:https://www.cnblogs.com/_programmer/p/1568052.html
Copyright © 2011-2022 走看看