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

数据结构+算法=程序

线性表的定义:具有相同特性的数据元素的一个有限序列。该序列中所含元素的个数叫做线性表长度。


定义:L=(a
1
,a
2,
a
3
….a
n
)

其中为a
1表头元素,为a
n表尾元素

线性表的顺序存储结构

其直接将线性表的逻辑结构映射到存储结构上

—————————————-

例:两线性表合并算法

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

线性表的
顺序存储类型可描述如下

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

(还请大家帮解答一下

    原文作者:约瑟夫环问题
    原文地址: https://www.cnblogs.com/_programmer/archive/2009/09/17/1568052.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞