数据结构学习笔记——线性表

数据结构+算法=程序

线性表的定义:具有相同特性的数据元素的一个有限序列。该序列中所含元素的个数叫做线性表长度。
定义: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,所以难免感到不适)
(还请大家帮解答一下

posted on 2009-09-17 09:38  ONLY LOVE PROGRAME  阅读(2049)  评论(0编辑  收藏  举报

导航