线性表的逻辑结构 线性表是一种最简单、最多见的数据结构算法
线性表是由n(n≥0)个数据元素(结点)a1,a2,a3,……an组成的有限序列。 数据元素的个数n定义为表的长度。 当n=0时,称为空表数据结构
将非空的线性表(n>0)记做:L=(a1,a2,a3,……,an) a1:起始结点,an:终端结点。 a1称为a2的直接前驱,a3称为a2的直接后继函数
线性表的特色:spa
线性表顺序存储的方法:将表中的结点依次存放在计算机内存 中的一组连续存储单元中。指针
数据元素在线性表中的邻接关系决定其在存储空间中的存储位置;即逻辑结构中相邻的结点,其存储位置也相邻。code
用顺序存储实现的线性表称为顺序表。blog
顺序表上的基本运算 : 插入(Insert)、删除(Delete)、定位(Locate)内存
=======================插入=========================it
线性表的插入运算:是指在表的位置i上,插入一个新结点x,使 长度为n的线性表(a1,a2,……,ai,……,an) 变为长度为n+1的线性表(a1,……,x,……,an)class
插入时的主义事项:
顺序表插入操做过程
插入算法的分析:
须要移动:10-4+1=7 ;7个节点
======================删除=====================
线性表的删除运算:是指将表的位置i的结点删去,使长度为n的线性 表(a1,a2,……,ai,……,an)变成长度为n-1的线性表 (a1,a2,……,ai-1,ai+1,……,an)
注意事项:当要删除元素的位置i不在表长范围内时,为非法位置,不能作正 常的删除操做
顺序表删除操做过程
假设线性表中含有n个数据元素,在进行删除操做时,有n个位置可删除, 在位置i删除时,要移动n-i个数据。
结论:顺序存储结构表示的线性表,在作插入或删除操做时,平均 须要移动大约一半的数据元素。当线性表的数据元素量较大, 而且常常要对其作插入或删除操做时,这一点须要考虑
===================定位=====================
定位:从第一个元素a1起,依次和x比较, 直到找到一个与x相等的数据元素,则 返回它在顺序表中的存储下标或序号;当查遍整个表都没找到与x相等的元 素,返回0。
定位算法的分析:
定位运算的功能是查找出线性表L中值等于x的结点序号的最小值,当不存 在这种结点时,结果为0。
i从0开始,做为扫描顺序表时的下标:
顺序表的特色:
顺序表的优势:
顺序表的缺点:
结点结构:
链表的具体存储表示为:
=================单链表===================
单链表的通常图示法:因为咱们经常只注重结点间的逻辑顺序,不关心每一个结点的实际位置,能够用 箭头来表示链域中的指针
单链表各个结点在内存中的存储位置(物理位置)并不必定连续
头结点:通常不存数据,利用Head存放该结点地址。在单链表中,增长头结点的目的是方便运算
单链表特色总结:
单链表的实现:
一、初始化
空表由一个头指针和一个头结点组成。算法描述以下: LinkList InitiateLinkList( ) //创建一个空的单链表 { LinkList head; //头指针 head=malloc (sizeof (Node) ) ; //动态构建一结点,它是头结点 head->next=NULL; return head; } 在算法中,变量head是链表的头指针,它指向新建立的结点,即头结点。一个空单链表仅有一个头结点,它的指针域为NULL。
二、求表长
在单链表存储结构中,线性表的长度等于单链表所 含结点的个数(不含头结点)
步骤:
int lengthLinklist (LinkList head){ Node *p; p=head; j=0; while( p->next != NULL ) { p=p->next; j++; } return(j); }
三、读表元素步骤:查找第i个结点
Node * GetlinkList( LinkList head, int i ){ Node *p; p=head->next; int c=1; while ((c<i) && (p!=NULL) ){ p=p->next; c++; } if(i= =c) return(p); else return NULL; }
四、删除节点
算法思路(此算法描述删除第i个结点)
① 找到第i-1个结点;若存在继续,不然结束;
② 删除第i个结点,并释放对应的内存,结束
删除运算是将表的第i个结点删去。
(1)找到ai-1的存储位置p
(2)令p->next指向ai的直接后继结点
(3)释放结点ai的空间,将其归还给"存储池" 。
算法的实现
在单链表中删除第 i 个结点的基本操做为:找到线 性表中第i-1个结点,修改其指向后继的指针。
void DeleteLinklist(LinkList head, int i) //删除表head的第i个结点 { Node *q; if(i==1) q=head; else q=GetLinklist(head, i-1); //先找待删结点的直接前驱 if(q !== NULL && q->next != NULL) //若直接前驱存在且待删结点存在 { p=q->next; //p指向待删结点 q->next=p->next; //移出待删结点 free(p); //释放已移出结点p的空间 } else exit (“找不到要删除的结点”); //结点不存在 }
注意:free(p)是必不可少的,由于当一个结点从链表移出后,若是不释放它的空间,它将变 成一个无用的结点,它会一直占用着系统内存空间,其余程序将没法使用这块空间
5. 定位
定位运算是对给定表元素的值,找出这个元素的位置。对 于单链表,给定一个结点的值,找出这个结点是单链表的 第几个结点。定位运算又称为按值查找
具体步骤:
int LocateLinklist(LinkList head, DataType x) //求表head中第一个值等于x的结点的序号,若不存在这种结点,返回结果为0 { Node *p=head; //p是工做指针 p=p->next; //初始时p指向首结点 int i=0; //i表明结点的序号,这里置初值为 while (p != NULL && p->data != x) //访问链表 { i++; p=p->next; } if (p!=NULL) return i+1; else return 0; }
六、插入
插入运算是将值为x的新结点插入到表的第i个结点 的位置上,即插入到ai-1与ai之间。
具体步骤:
void InsertLinklist (LinkList head, DataType x, int i) //在表head的第i个数据元素结点以前插入一个以x为值的新结点 { Node *p,*q; if (i==1) q=head; else q=GetLinklist (head, i-1); //找第 i-1个数据元素结点 if (q==NULL) //第i-1个结点不存在 exit(“找不到插入的位置”); else { p=malloc(sizeof (Node) );p->data=x; //生成新结点 p->next=q->next; //新结点链域指向*q的后继结点 q->next=p; //修改*q的链域 } }
注意:连接操做p->next=q->next和q->next=p两条语句的执行顺序不能颠倒,不然结点 *q的链域值(即指向原表第i个结点的指针)将丢失。
七、清除单链表中值为x的重复结点
步骤:
void PurgeLinklist(LinkList head) //删除表head中多余的重复结点 { Node *p,*q,*r; q=head->next; //q指示当前检查结点的位置,置其初值指向首结点 while(q!=NULL) //当前检查结点*q不是尾结点时,寻找并删除它的重复结点 { p=q; //工做指针p指向*q while(p->next!=NULL) //当*p的后继结点存在时,将其数据域与*q数据域比较 { if (p->next->data==q->data) //若*(p->next)是*q的重复结点 { r=p->next; //r指向待删结点 p->next = r->next; //移出结点* (p->next),p->next指向原来* (p->next)的后继结点 free (r); } else p=p->next; //不然,让p指向下一个结点 } q=q->next; //更新检查结点 } }
线性表的基本运算
1,初始化 Initiate(L) 创建一个空表L=(),L不含数据元素。
2,求表长度 Length(L) 返回线性表L的长度。
三、取表元 Get(L,i) 返回线性表第i个数据元素,当i不知足 1≤i≤Length(L)时,返回一特殊值
四、定位 Locate(L,x) 查找线性表中数据元素值等于x的结点序号,如有多 个数据元素值与x相等,运算结果为这些结点中序号 的最小值,若找不到该结点,则运算结果为0
五、插入 Insert(L,x,i) 在线性表L的第i个数据元素以前插入一个值为x的新数据 元素,参数i的合法取值范围是1≤i≤n+1。操做结束后线性 表L由(a1,a2,…,ai-1, ai,ai+1,.…,an )变为(a1,a2, …,ai-1,x, ai,ai+1,.…,an ),表长度加 1。
六、删除 Delete(L,i) 删除线性表L的第i个数据元素ai,i的有效取值范围是1≤i≤n。 删除后线性表L由(a1,a2,…,ai-1, ai,ai+1,.…,an )变为 (a1,a2,…,ai-1,ai+1,.…,an ),表长度减1
一、循环链表
如何找到循环链表的尾结点
在循环链表中附设一个rear指针指向尾结点 适用于常常适用头尾结点的链表操做中
二、双向循环链表
在链表中设置两个指针域, 一个指向后继结点 一个指向前驱结点 这样的链表叫作双向链表
线性表与链表的优缺点:
(1)单链表的每一个结点包括数据域与指针域,指针域须要占用额外空间。
(2)从总体考虑,顺序表要预分配存储空间,若是预先分配得过大,将形成 浪费,若分配得太小,又将发生上溢;单链表不须要预先分配空间,只 要内存空间没有耗尽,单链表中的结点个数就没有限制。