-
2019-07-29 16:45:22
数据结构中的物理结构包含有:顺序存储结构与链式存储结构
存储优缺点:
- 顺序存储结构在未达到内存限制时,(因为是顺序存储所以查询尾部比较快)在末尾插入比较快,但是在中间插入,需要将当前插入位置的元素及后面元素统一往后移动一位;删除非尾端元素时,需要将当前删除元素后面的所有元素往前移动一个。
- 链式存储结构不需要考虑内存限制,插入与删除速度很快,因为链式结构是前后索引方式(即元素会存放它的前一个元素和下一个元素的坐标),查询比较慢,链式结构只能通过从前往后遍历的方式去查询。
用法1:
- 查询频繁
- 存储量固定
建议使用顺序结构:因为已知存储量固定大小,可以直接去内存中开辟一个固定大小的空间。
用法2:
- 插入与删除频繁
- 存储量不固定
建议使用链式存储结构:因为不清楚存储量,而链式结构在内存中,并非连续且相邻的,插入与删除链式结构效率要远远大于顺序结构
更多相关内容 -
链式存储结构的特点
2017-10-31 17:04:48链式存储结构的特点 1.优点 1.存储空间动态分配,可以根据实际需要使用 2.不需要地址连续的存储空间 3.插入/删除操作只须通过修改指针实现,不必移动数据元素,操作时间效率高 (无论位于链表何处...链式存储结构的特点
1.优点
1.存储空间动态分配,可以根据实际需要使用
2.不需要地址连续的存储空间
3.插入/删除操作只须通过修改指针实现,不必移动数据元素,操作时间效率高 (无论位于链表何处无论链表长度如何,插入和删除操作的时间都是O(1))
2.缺点
1.每个链结点需要设置指针域(存储密度小)
2.是一种非随机存储结构,查找、定位等操作要通过顺序扫描链表实现,时间效率低O(n)
例题:
请写一个算法,该算法尽可能高的时间效率找到由list所指的线性链表的倒数第k个结点。若找到这样的结点,算法给出该结点的地址,否则给出NULL
限制:1.算法中不得求出链表长度,也不允许对链表进行逆转
2.不允许使用除指针变量和控制变量以外的其他辅助空间
1.设置一个指针变量p,初始时指向链表的第一个结点
2.然后令p后移指向链表的第k个结点 执行k-1次
3.再设置另一个指针变量q,初始时指向链表的第一个结点
4.利用一个循环让p q 同步沿链表向后移动;当p指向链表最后那个结点时,q指向链表的倒数第k个结点 执行n-k次
LinkList SEARCHNODE(LinkList list, int k)
{
LinkList p,q;
int i;
if (list != NULL && k > 0) {
p = p ->link;
if(p == NULL) {
printf(“链表中不存在倒数第k个结点”);
return NULL;
}
}
q = list;
while(p -> link != NULL) {
p = p ->link;
q = q ->link;
}
return q;
}
-
二叉树的链式存储结构(线索二叉树)
2021-02-05 10:52:42一、链式存储结构 由于顺序存储二叉树的空间利用率较低,因此二叉树一般都采用链式存储结构,用链表结点来存储二叉树中的每个结点。在二叉树中,结点结构通过包括若干数据域和若干指针域,二叉链表至少包含3个域:...一、链式存储结构
由于顺序存储二叉树的空间利用率较低,因此二叉树一般都采用链式存储结构,用链表结点来存储二叉树中的每个结点。在二叉树中,结点结构通过包括若干数据域和若干指针域,二叉链表至少包含3个域:数据域 data、左指针域 lchild和右指针域 rchild,如下图所示:
其中,n 个结点的二叉链表中含有 n+1 [ 2n-(n-1)=n+1 ] 个空指针域。二、线索二叉树
传统的二叉链表仅能体现出一种父子关系,不能直接得到结点在遍历中的前驱或后继。引入线索二叉树正是为了加快查找结点前驱和后继的速度。
规定:若无左子树,令 lchild指向其前驱结点;若无右子树,令rchild执行指向其后继结点。增加两个标志域标识是指向左/右孩子还是指向前驱/后继。
其标志位含义如下:
这种加上线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。根据线索性质的不同, 线索二叉树可分为前序线索二叉树、 中序线索二叉树和后序线索二叉树三种。
1.1、中序线索二叉树
1.1.1 中序线索二叉树的构造设置结点pre指向刚刚访问过的结点,结点node指向正在访问的结点,即pre指向node的前驱。在遍历过程中,检查node的左指针是否为空,若为空就将它指向pre;检查pre的右指针是否为空,若为空就将它指向node。
public static void inthreadNode(Node node) { if(node==null) {//结点为空无法线索化 return; } //线索化左子树 inthreadNode(node.getLeft()); //线索化当前结点 if(node.getLeft()==null) { node.setLeft(pre);//让当前结点的左指针指向前驱结点 node.setLtag(1);//修改当前结点的左指针的类型,指向前驱结点 } if(pre!=null&&pre.getRight()==null) { pre.setRight(node);//让前驱结点的右指针指向当前结点 pre.setRtag(1);//修改当前结点的右指针的类型,指向后继结点 } pre=node;//每处理一个结点后,让当前结点成为刚刚访问过的结点 //线索化右子树 inthreadNode(node.getRight()); }
1.1.2 中序线索二叉树的遍历
因为线索化后, 各个结点指向有变化, 因此原来的遍历方式不能使用, 需要使用新的方式遍历线索化二叉树。中序线索二叉树的结点中隐含了线索二叉树的前驱和后继信息。在对其遍历时,需要找到第一个具有前驱结点的左结点,然后依次找结点的后继。在中序线索二叉树中找结点后继的规律是:若其右标志为1,则右链为线索,指示其后继,否则遍历右子树中第一个访问的结点(右子树中最左下的结点)为其后继。
public static void inthreadlist(Node node) { node=root;//存储当前遍历的结点,从root开始 while(node!=null) { while(node.getLtag()==0) { node=node.getLeft(); } System.out.println(node);//打印当前结点 while(node.getRtag()==1) {//获取到当前结点的后继结点 node=node.getRight(); System.out.println(node); } node=node.getRight();//依次替换遍历的结点 } }
1.1.3 中序线索二叉树完整代码
package Tree; public class InThreadedBinaryTree { public static void main(String[] args) { Node root=new Node(7,"A");//创建二叉树 Node a=new Node(4,"B"); Node b=new Node(9,"C"); Node c=new Node(2,"D"); Node d=new Node(5,"E"); Node e=new Node(8,"F"); Node f=new Node(11,"G"); Node g=new Node(1,"H"); Node h=new Node(3,"I"); Node i=new Node(10,"J"); Node j=new Node(12,"K"); root.setLeft(a); root.setRight(b); a.setLeft(c); a.setRight(d); b.setLeft(e); b.setRight(f); c.setLeft(g); c.setRight(h); f.setLeft(i); f.setRight(j); inThreadBinaryTree thread=new inThreadBinaryTree(root); inThreadBinaryTree.inthreadNode(root);//创建中序线索二叉树 inThreadBinaryTree.inthreadlist(root);//遍历中序线索二叉树 } } class Node{ private int data; private String name; private Node left;//默认null private Node right;//默认null //若ltag == 0,说明指向的是左子树;ltag == 1,指向的是前驱结点 //若rtag == 0,说明指向的是右子树;rtag == 1,指向的是后继结点 private int ltag; private int rtag; public Node(int data,String name) { this.data=data; this.name=name; } public int getData() { return data; } public void setData(int data) { this.data = data; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } public int getLtag() { return ltag; } public void setLtag(int ltag) { this.ltag = ltag; } public int getRtag() { return rtag; } public void setRtag(int rtag) { this.rtag = rtag; } @Override public String toString() {//重写toString方法 return "Node [data=" + data + ", name=" + name + "]"; } } //中序线索化二叉树(左->根->右) class inThreadBinaryTree{ private static Node root; private static Node pre=null;//pre表示刚刚访问过的结点,即前一个结点 public inThreadBinaryTree(Node root) {//inThreadBinaryTree构造函数 this.root=root; } public static void inthreadNode(Node node) { if(node==null) {//结点为空无法线索化 return; } //线索化左子树 inthreadNode(node.getLeft()); //线索化当前结点 if(node.getLeft()==null) { node.setLeft(pre);//让当前结点的左指针指向前驱结点 node.setLtag(1);//修改当前结点的左指针的类型,指向前驱结点 } if(pre!=null&&pre.getRight()==null) { pre.setRight(node);//让前驱结点的右指针指向当前结点 pre.setRtag(1);//修改当前结点的右指针的类型,指向后继结点 } pre=node;//每处理一个结点后,让当前结点成为刚刚访问过的结点 //线索化右子树 inthreadNode(node.getRight()); } //中序线索化二叉树的遍历(遍历次序和中序遍历保持一致) public static void inthreadlist(Node node) { node=root;//存储当前遍历的结点,从root开始 while(node!=null) { while(node.getLtag()==0) { node=node.getLeft(); } System.out.println(node);//打印当前结点 while(node.getRtag()==1) {//获取到当前结点的后继结点 node=node.getRight(); System.out.println(node); } node=node.getRight();//依次替换遍历的结点 } } }
运行结果:
Node [data=1, name=H] Node [data=2, name=D] Node [data=3, name=I] Node [data=4, name=B] Node [data=5, name=E] Node [data=7, name=A] Node [data=8, name=F] Node [data=9, name=C] Node [data=10, name=J] Node [data=11, name=G] Node [data=12, name=K]
该实例的二叉树图如下图所示:
2.1、前序线索二叉树和后序线索二叉树
-
线性表的链式存储结构
2022-01-21 21:59:42一、线性表的链式存储结构 1、定义 线性表的链式存储单元的特点是用一组任意的存储单元存储线性表的数据元素,我们除了要存储它的元素信息外,我们还要存储它们的后继元素的存储地址。 如上图所示,在我们的节点...一、线性表的链式存储结构
1、定义
线性表的链式存储单元的特点是用一组任意的存储单元存储线性表的数据元素,我们除了要存储它的元素信息外,我们还要存储它们的后继元素的存储地址。
如上图所示,在我们的节点中分数据域和指针域,指针域中存放的便是下一个结点的地址,如上图存放的0500便是下一个结点的地址。2、头指针or头节点
头指针
- 头指针是指链表指向的第一个节点的指针,若链表有头节点,则是指向头节点的指针
- 头指针有标志作用,一般用头指针冠以链表的名字。
- 不论链表是否为空,头指针均不为空。
头节点 - 头节点是为了操作的方便而设立的,数据域一般无意义。
- 有了头节点,对在第一元素节点前插入节点和删除节点等操作就统一了。
- 头节点不一定是链表必须要素。
二、单链表的读取
我们要获取第i个数据的算法思路,没办法一开始就知道,链表的查找比较麻烦。
- 声明一个节点p指向链表的第一个结点,初始化j从1开始;
- 当j<i时候,就遍历链表,让p的指针向后移,不断指向下一个节点,j累加。
- 若到链表末尾p为空,则说明第i个元素不存在;
- 否则查找成功,返回节点p的数据。
说白了,就是从头开始找,直到第 i 个元素为止,因为不知道要循环多少次,所以我们不能用for循环,核心思想还是指针后移。
三、单链表的插入与删除
1、插入
如上图图所示,单链表的插入,需要先断开上面两个节点关系,让 p 的指针域存放 e 的地址,然后把之前 p 的下一个节点的地址给e的指针域。插入后如图所示:
当然,表头和表尾的操作也是一样,表头的操作就是把新的表头的指针域里存放之前表头的地址,表尾增加则是把新表尾的地址放在之前表尾的指针域。2、单链表的删除
单链表的删除操作,也就是把上图所示的ai节点删除,我们只需要把ai+1结点的地址交给ai-1的指针域即可。
我们可以明显看到看到,对于插入删除数据越频繁的操作,单链表的优势是十分的明显,他们的时间复杂度都是O(1)。三、单链表的整表创建
1、头插法
创建单链表的过程就是一个动态生成链表的过程,单链表头插法的思路是:
5. 声明一个节点p和计数变量i;
6. 初始化一空链表L;
7. 让L的头节点的指针指向null,建立一个带头结点的单链表。
8. 循环:
①生成一新结点赋值给P;
②随机生成艺术字赋值给p的数据域;
③将p插入到头节点与前一新结点之间。
2、尾插法
尾插法即我们在标为添加,我们设 r 为指向尾结点的变量,r 会随着循环不断的变化结点,而L我们定义为整个单链表,我们把原先的 r 的指针域存放新的尾结点的地址,然后我们最后让 r 拿到新的尾结点的地址,这样就完成了尾插法。
四、单链表的整表删除
单链表的整表删除也是要一个一个来,不能直接删除,要把下一个结点的值拿到后再删除本结点,不然找不到下一个节点在哪。步骤:
- 声明节点p和q;
- 将第一个结点赋给p;
- 循环:先将下一个节点赋值给q,然后释放p,然后把q赋给p,如此循环。
-
二叉树的链式存储结构
2019-04-22 19:27:38二叉树的链式存储结构就是用链表来表示一棵二叉树,即用链表来指示元素之间的逻辑关系。通常有两种存储形式: 链表中每个结点由三个域组成,除了数据域之外,还有两个指针域,分别用来给出该结点的左孩子和右孩子... -
细说链式存储结构
2018-10-13 13:31:49提起链式存储结构,其与数组是两个非常基础的数据结构,每当提到链式存储结构时,一般情况下我们都会将其与数组放到一块儿来比较。 对于数组与链表,从结构上来看,数组是需要一块连续的内存空间来存储数据,对内存... -
线性表_顺序存储结构和链式存储结构的优缺点比较
2022-05-15 22:14:09链式存储时,相邻数据元素可以随意存放,但是所占存储空间分两部分,一部分存放结点值,另一部分存放指针。 优点:插入删除元素很方便,存储空间利用率高 缺点:存储密度小,查找和修改需要遍历整个链表。 . -
队列的链式存储结构
2022-04-24 19:44:42队列的链式存储结构:只能尾进头出的单链表也叫链队列。 与顺序存储结构一样有front指针和rear指针,只不过front指向头结点,rear指向最后一个结点。 当front指针和rear指针都指向头结点时,链表为空。 链... -
顺序存储结构和链式存储结构的优缺点比较
2018-10-09 17:45:34顺序存储结构和链式存储结构的比较 优缺点 顺序存储时,相邻数据元素的存放地址也相邻(逻辑与物理统一);要求内存中可用存储单元的地址必须是连续的。 优点:存储密度大(=1),存储空间利用率高。 缺点:... -
数据结构与算法4——链式存储结构
2019-08-02 15:26:03线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以在内存中未被占用的任意位置。 比起顺序存储结构每个数据元素只需要存储一个位置就可以了。现在链式存储结构中,除了要... -
数据结构第六篇——顺序存储结构与链式存储结构的特点
2017-09-21 18:44:00顺序表的特点是逻辑上相邻的数据元素,物理存储位置也相邻,并且,顺序表的存储空间需要预先分配。 它的优点: (1)方法简单,各种高级语言中都有数组,容易实现。 (2)不用为表示节点间的逻辑关系而增加... -
数据结构——顺序存储结构&链式存储结构的区别和用法
2020-02-10 18:17:27目录: 一:线性表的顺序存储结构 1.定义 2.顺序存储示意图如下所示: ...二:线性表的链式存储结构 1.什么是链表 2.结点 (1)数据域 (2)指针域 3.头指针&头结点 (1)头指针 (2)... -
数据结构之链式存储结构和顺序存储结构
2019-12-26 23:36:02顺序存储结构: 定义:在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,以数据元素为单位,按数据元素在表中的次序存储。...链式存储结构: 种类:单链表、循环链表和双向链表 ... -
二叉树的存储结构顺序存储和链式存储
2021-05-16 13:54:04顺序存储 实现:将一棵二叉树按照当做一棵满二叉树进行编号(从上到下,从左到右),编号作为数组的下标,一次存放到二叉树的数据元素。 当一个二叉树不是完全二叉树,那么总会有一些位置没有元素,那么就将这些位置... -
[数据结构] 线性表---链式存储结构
2019-07-31 09:49:001.线性表的链式存储结构定义 2.线性表链式存储结构代码描述 3.对单链表的整表创建、整表删除、插入、删除、读取 4.比较链式存储结构和线性存储结构 -
(数据结构)线性表(总结)——链式存储结构与顺序储存结构的优缺点
2021-08-13 09:34:47链式存储结构是一组任意的存储单元,存放线性表的元素。 2、时间性能a、查找 顺序存储结构:0(1) 链式存储结构:0(n)b、插入和删除 顺序存储结构的插入和删除需要平均线性表的长度一半的元素,时间是0(n)。 链式存储... -
数据结构-线性表(链式存储结构)
2020-09-20 11:55:49线性表(链式存储结构) 特点: 用一组任意的存储单元存储线性表的数据结构,这组存储单元可以是连续的,也可以是不连续的。 对数据结构ai来说,除了存储其本身的信息之外,还需存储一个指示其后继的信息(即直接... -
搞懂数据结构——线性表的顺序、链式存储结构
2022-03-18 11:07:09一篇文章带你了解线性表的顺序、链式存储结构 -
线性表之顺序存储结构和链式存储结构
2018-09-28 14:17:06顺序存储结构和链式存储结构有所不同,具体区别如下表所示: 通过上面的对比,可以得出一些经验性的结论: 若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。若需要频繁插入和删除时,宜... -
数据结构与算法(三)链式存储结构(单链表)
2021-09-23 22:05:50链式存储结构:结点在存储器中的位置是任意的,即逻辑相邻的数据元素物理上不一定相邻。又称为非顺序映像或链式映像 实现:用一组物理位置任意的存储单元来存放线性表的数据元素,这组存储单元可以连续也可以不连续... -
(数据结构)实验二 线性表的链式存储结构
2020-06-11 22:13:282、 熟练掌握线性表的链式存储结构的定义及其基本操作的C 语言实现。 3、掌握单向链表、单向循环链表的应用,逐步培养解决实际问题的能力。 4、能够从时间和空间复杂度的角度综合比较线性表两种存储结构的不同特点... -
栈的顺序与链式存储结构及实现(C语言)
2022-03-25 17:30:34} 2.2 链栈的表示和实现 2.2.1 栈的链式存储表示 链栈是指采用链式存储结构实现的栈。通常链栈用单链表来表示。链栈的结点结构与单链表相同,在此用StackNode表示。 2.2.2 链栈的定义与基本操作函数源码 // // ... -
链式存储结构即链式结构简单介绍
2016-08-15 12:35:56链式结构简单介绍链式结构是一种数据结构,学名链式存储结构,又叫链接存储结构。使用对象引用变量来创建对象间的链接。它不要求逻辑上相邻的元素在物理位置上也相邻。因此它没有顺序存储结构所具有的弱点,同时也... -
【数据结构】线性结构——线性表之链式存储结构(链表)
2020-09-13 18:09:22为了克服顺序表存储结构的缺点,充分利用存储空间和提高运行效率,线性表可以采用另一种存储结构——链式存储结构。线性表的链式存储结构简称“链表(link list)” 一、链表概述 链表的数据元素所占的存储单元... -
数据结构之线性表的链式存储结构(C语言)
2020-05-25 13:12:33线性表的顺序存储结构,它是有缺点的,最大的缺点就是插入和删除时需要移动大量的数据元素,这显然需要耗费时间。 线性表链式存储结构定义 特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续... -
链式存储结构优缺点
2018-09-07 14:15:27顺序表的特点是逻辑上相邻的数据元素,物理存储位置也相邻,并且,顺序表的存储空间需要预先分配。 它的优点: (1)方法简单,各种高级语言中都有数组,容易实现。 (2)不用为表示节点间的逻辑关系而增加... -
数据结构复习2:线性表的链式存储结构
2020-04-15 22:00:42复习数据结构线性表的基本操作 线性表的链式表示和实现 -
数据结构 - 顺序存储结构和链式存储结构
2019-06-12 14:05:00数据结构 - 顺序存储结构和链式存储结构 顺序存储结构 顺序存储中,相邻数据元素的存放地址也相邻,内存中存储单元的地址必须是连续的,存储密度 = 1。 优点: 不用为表示节点间的逻辑关系而... -
C语言数据结构-顺序表的链式存储结构
2020-12-15 12:05:00本期推文主要给大家介绍顺序表的链式存储结构,了解并掌握链式存储结构的特点及基本定义,并学会单链表的基本操作及其初始化方法。 特点 线性表中的数据元素在存储单元中的存放顺序与逻辑顺序不一定一致 通过头指针...