软考路之线性表
2015-10-04 16:49
232 查看
背景:数据结构导论中介绍了什么是线性表以及线性表的存储,软考学习中也有这部分的内容,自己对这部分有点抵触,感觉乱乱的,现在梳理总结一下,同时消除心中的抵触。
一、线性表(Linear List)
是一种线性结构,由n(n>=0)个元素组成的有穷序列,数据元素又称结点,结点个数n称为表长。
二、基本特征
1、线性表中结点具有一对一的关系
2、若结点数不为0,则除起始结点没有直接前驱外,其他每个结点有且仅有一个直接前驱。
3、若结点数不为0,则除终端结点没有直接后继外,其他每个结点有且仅有一个直接后继。
4、线性表中每个数据元素的含义在不同的应用中各不相同,但同一个线性表中的所有结点代表的数据元素具有相同的特性。
三、顺序存储
将表中的结点依次存放在计算机内存中一组连续的存储单元中,数据元素在线性表中的邻接关系决定他们在存储空间中的存储位置,即逻辑结构中相邻的结点其存储位置也相邻。
用顺序存储实现的线性表称为顺序表,一般用数组来表示顺序表。
顺序表中的“第i个数据元素”存放在数组下标为“i-1”的位置。
![](https://img-blog.csdn.net/20151004112039763?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
1、插入
首先,将结点ai~an依次向后移动一个元素的位置,空出第i个数据元素的位置。
然后,将x置入该空位。
最后,表长加1。
2、删除
首先,结点a(i+1), ... ,an依次向左移动一个元素位置(从而覆盖掉被删除的结点ai)
然后,表长度减1。
3、定位
查找出线性表L中值等于x的结点序号的最小值,当找不到值为x的结点是,返回结果为0。
四、链接存储
指它的存储结构是链式的,常见的链式存储结构有单链表、循环链表和双向循环链表。
结点结构
![](https://img-blog.csdn.net/20151004152651421)
单链表示例
![](https://img-blog.csdn.net/20151004153929102?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
变量head是链表的头指针,指向新创建的结点,即头结点。
1、初始化
首先,创建一个头结点并将其指针域设为NULL(标识该结点不指向任何结点)
然后,用一个LinkList类型(即结点的指针类型)的变量指向新创建的结点。
2、求表长
在单链表存储结构中,线性表的表长等于单链表中数据元素的结点个数,即除了头结点以外的结点的个数。
3、读表元素
必须从头指针出发,一直往后移动,直到第i个结点。
4、定位
对给定表元素的值,找出这个元素的位置。需要从头至尾访问链表,直至找到需要的结点,返回其序号。若未找到,返回0.
5、插入
首先,找到链表的第i-1个结点q.
然后,生成一个值为x的新结点p,
最后,p的指针域指向q的直接后继结点,q的指针与指向p.
6、删除
给定一个值i,将链表中第i个结点从链表中移出,并修改相关结点的指针域,以维持剩余结点的链接关系。
五、比较
![](https://img-blog.csdn.net/20151004164139107?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
总之,线性表的顺序实现与链接实现各有其优缺点,不能笼统地说哪种实现更好,只能根据实际问题的具体需要,并对各方面的优缺点加以综合平衡,最终选定比较适宜的实现方法。
六、学习心得
虽然有点乱,但是,整理一下就会好很多,现在感觉,对这方面的了解多了一点。
博客不光是写给别人看的,更是自己学习轨迹的体现,把不会的,不清楚的整理下来,后期翻阅的时候,就会有新的体会。同时,在整理的时候,是自己收获比较大的时候。
一、线性表(Linear List)
是一种线性结构,由n(n>=0)个元素组成的有穷序列,数据元素又称结点,结点个数n称为表长。
二、基本特征
1、线性表中结点具有一对一的关系
2、若结点数不为0,则除起始结点没有直接前驱外,其他每个结点有且仅有一个直接前驱。
3、若结点数不为0,则除终端结点没有直接后继外,其他每个结点有且仅有一个直接后继。
4、线性表中每个数据元素的含义在不同的应用中各不相同,但同一个线性表中的所有结点代表的数据元素具有相同的特性。
三、顺序存储
将表中的结点依次存放在计算机内存中一组连续的存储单元中,数据元素在线性表中的邻接关系决定他们在存储空间中的存储位置,即逻辑结构中相邻的结点其存储位置也相邻。
用顺序存储实现的线性表称为顺序表,一般用数组来表示顺序表。
顺序表中的“第i个数据元素”存放在数组下标为“i-1”的位置。
1、插入
首先,将结点ai~an依次向后移动一个元素的位置,空出第i个数据元素的位置。
然后,将x置入该空位。
最后,表长加1。
void InsertSeqlist(SeqList L, DataType x ,int i) { //将元素x插入到顺序表L的第i个数据元素之前 if(L.length==Maxsize) exit(“表已满”); if(i<1 || i>L.length+1) exit(“位置错”); //检查插入位置是否合法 for(j=L.length;j>=I;j--) //初始i=L.length L.data[j]=L.data[j-1]; //依次后移 L.data[i-1]=x; //元素x置入到下标为i-1的位置 L.length++; //表长度加1 }
2、删除
首先,结点a(i+1), ... ,an依次向左移动一个元素位置(从而覆盖掉被删除的结点ai)
然后,表长度减1。
void DeleteSeqlist(SeqList L, int i) { //删除线性表L中的第i个数据结点 if(i<1 || i>L.length) exit(“位置错”); //检查插入位置是否合法 for(j=I ; j<L.length;j++) //第i个元素的下标为i-1 L.data[j-1]=L.data[j]; //依次左移 L.length--; //表长度减1 }
3、定位
查找出线性表L中值等于x的结点序号的最小值,当找不到值为x的结点是,返回结果为0。
void LocateSeqlist(SeqList L, DataType x) { int i=0; while ((i<L.length) && (L.data[i]!=x)); //在顺序表中查找值为x的结点 i++; if (i<L.length) return i+1; //若找到值为x的元素,返回元素的序号 else return 0; //未找到值为x的元素,返回0 }
四、链接存储
指它的存储结构是链式的,常见的链式存储结构有单链表、循环链表和双向循环链表。
结点结构
单链表示例
变量head是链表的头指针,指向新创建的结点,即头结点。
1、初始化
首先,创建一个头结点并将其指针域设为NULL(标识该结点不指向任何结点)
然后,用一个LinkList类型(即结点的指针类型)的变量指向新创建的结点。
LinkList InitiateLinkList() //创建一个空的单链表 { LinkList head; //头指针 head=malloc(sizeof(Node)); //动态构建一结点,它是头结点 head—>next=Null; return head; }
2、求表长
在单链表存储结构中,线性表的表长等于单链表中数据元素的结点个数,即除了头结点以外的结点的个数。
int LengthLinklist(LickList head) //求单链表head的长度 { Node * p=head; //p是工作指针,初始时p指向头结点 int cnt=0; //计数器置初值 while (p—>next !=NULL) //判断是否为尾结点 { p= p—>next; //指针移动到下一个结点 cnt++; } return cnt; //返回表长 }
3、读表元素
必须从头指针出发,一直往后移动,直到第i个结点。
Node * GetLinklist(LinkList head , int i) //在单链表head中查找第i个元素结点。若找到,则返回指向该结点的指针;否则返回NULL { Node * p; //p是工作指针 P=head—>next; //初始时,p指向首结点 int c=1; while ((c<i) && (p!=NULL)) //当未到第i结点且未到尾结点时继续后移 { p=p—>next; c++;} If (i==c) return p; //找到第i个结点 else return NULL; //i<1或i>n,i值不合法,查找失败 }
4、定位
对给定表元素的值,找出这个元素的位置。需要从头至尾访问链表,直至找到需要的结点,返回其序号。若未找到,返回0.
int LocateLinklist(LinkList head ,DataType x) //求表head中第一个值等于x的结点的序号,若不存在这种结点,返回0 { Node * p=head; //p是工作指针 p=p—>next; //初始时p指向首结点 int i=0; //i代表结点的序号,这里置初始值为0 while (p!=NULL && p—>data!=x) //访问链表 { i++; p=p—>next; } if (p!=NULL) return i+1; else return 0; }
5、插入
首先,找到链表的第i-1个结点q.
然后,生成一个值为x的新结点p,
最后,p的指针域指向q的直接后继结点,q的指针与指向p.
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; <span style="white-space:pre"> </span> //新结点链域指向*q的后继结点 q—>next=p; //修改*q的链域 } }
6、删除
给定一个值i,将链表中第i个结点从链表中移出,并修改相关结点的指针域,以维持剩余结点的链接关系。
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(“找不到要删除的结点”); //结点不存在 }
五、比较
总之,线性表的顺序实现与链接实现各有其优缺点,不能笼统地说哪种实现更好,只能根据实际问题的具体需要,并对各方面的优缺点加以综合平衡,最终选定比较适宜的实现方法。
六、学习心得
虽然有点乱,但是,整理一下就会好很多,现在感觉,对这方面的了解多了一点。
博客不光是写给别人看的,更是自己学习轨迹的体现,把不会的,不清楚的整理下来,后期翻阅的时候,就会有新的体会。同时,在整理的时候,是自己收获比较大的时候。
相关文章推荐
- C/C++字节与内存问题
- Scala学习笔记03【学习识别Scala函数式风格】
- 【Redis常见问题】
- salt stack的远程命令如何执行-笔记
- Spring s2sh 整合(二)
- 信息安全系统设计基础第四周学习总结
- 如何盗取别人的QQ密码
- pat1022Digital Library (30)
- LintCode 丢失的第一个正整数
- 小圆大圆转圈问题
- SQL Server与Oracle的一些区别
- Java——Thread/Runnable实现多线程
- win10预览版10558怎么样 win10预览版10558上手体验视频
- Java——Thread/Runnable实现多线程
- XML数据解析-SAX和DOM
- Shell基础-Bash变量-用户自定义变量
- Python爬虫的一些总结
- 零碎知识点(未分类)
- HTTPS协议简介
- linux c 获取硬盘序列号