您的位置:首页 > 理论基础 > 数据结构算法

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

2009-09-17 09:38 363 查看
.O {color:#006699; font-size:149%;} a:link {color:#CC99FF !important;} a:active {color:#EBF7FF !important;} a:visited {color:#F2DFFD !important;} .O {color:black; font-size:149%;} a:link {color:red !important;} a:active {color:#FFCF01 !important;} a:visited {color:#3333CC !important;} #define MAXSIZE 50

typedef struct

{

ElemType date[MAXSIZE];

int length;

}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,所以难免感到不适)

(还请大家帮解答一下)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: