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,所以难免感到不适)
    (还请大家帮解答一下
  • 相关阅读:
    codeforces C. No to Palindromes!
    codeforces D. Pashmak and Parmida's problem
    codeforces C. Little Pony and Expected Maximum
    codeforces D. Count Good Substrings
    codeforces C. Jzzhu and Chocolate
    codeforces C. DZY Loves Sequences
    codeforces D. Multiplication Table
    codeforces C. Painting Fence
    hdu 5067 Harry And Dig Machine
    POJ 1159 Palindrome
  • 原文地址:https://www.cnblogs.com/_programmer/p/1568052.html
Copyright © 2011-2022 走看看