iOS开发算法--链表
2017-05-23 15:14
344 查看
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
![](http://upload-images.jianshu.io/upload_images/1170656-04b5a2f0d9ebde71.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
详细代码请参考Algorithm。参考代码比文字好理解。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。
总结来说,相比较普通的线性结构,链表结构的优势是单个节点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的大小;节点的删除非常方便,不需要像线性结构那样移动剩下的数据;节点的访问方便,可以通过循环或者递归的方法访问到任意数据,但是平均的访问效率低于线性表。
![](http://upload-images.jianshu.io/upload_images/1170656-c952b05aa519d18e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
存储结构
线索二叉树(保留遍历时结点在任一序列的前驱和后继的信息):若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其前驱;若结点有右子树,则其rchild域指示其右孩子,否则令rchild指示其后继。还需在结点结构中增加两个标志域LTag和RTag。LTag=0时,lchild域指示结点的左孩子,LTag=1时,lchild域指示结点的前驱;RTag=0时,rchild域指示结点的右孩子,RTag=1时,rchild域指示结点的后继。
以这种结点结构构成的二叉线索链表,链表作为二叉树的存储结构,叫做其中指向结点前驱和后继的指针叫做线索,加上线索的二叉树称为线索二叉树。对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化。若对二叉树进行中序遍历,则所得的线索二叉树称为中序线索二叉树,线索链表称为为中序线索链表。线索二叉树是一种物理结构。
在中序线索树找结点后继的规律是:若其右标志为1,则右链为线索,指示其后继,否则遍历其右子树时访问的第一个结点(右子树最左下的结点)为其后继;找结点前驱的规律是:若其左标志为1,则左链为线索,指示其前驱,否则遍历左子树时最后访问的一个结点(左子树中最右下的结点)为其前驱。
在后序线索树中找到结点的后继分三种情况:
若结点是二叉树的根,则其后继为空;若结点是其双亲的右孩子,或是其双亲的左孩子且其双亲没有右子树,则其后继即为双亲结点;若结点是其双亲的左孩子,且其双亲有右子树,则其后继为双亲右子树上按后序遍历列出的第一个结点。
![](http://upload-images.jianshu.io/upload_images/1170656-04b5a2f0d9ebde71.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
详细代码请参考Algorithm。参考代码比文字好理解。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。
总结来说,相比较普通的线性结构,链表结构的优势是单个节点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的大小;节点的删除非常方便,不需要像线性结构那样移动剩下的数据;节点的访问方便,可以通过循环或者递归的方法访问到任意数据,但是平均的访问效率低于线性表。
线索二叉树
![](http://upload-images.jianshu.io/upload_images/1170656-c952b05aa519d18e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
存储结构
线索二叉树(保留遍历时结点在任一序列的前驱和后继的信息):若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其前驱;若结点有右子树,则其rchild域指示其右孩子,否则令rchild指示其后继。还需在结点结构中增加两个标志域LTag和RTag。LTag=0时,lchild域指示结点的左孩子,LTag=1时,lchild域指示结点的前驱;RTag=0时,rchild域指示结点的右孩子,RTag=1时,rchild域指示结点的后继。
以这种结点结构构成的二叉线索链表,链表作为二叉树的存储结构,叫做其中指向结点前驱和后继的指针叫做线索,加上线索的二叉树称为线索二叉树。对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化。若对二叉树进行中序遍历,则所得的线索二叉树称为中序线索二叉树,线索链表称为为中序线索链表。线索二叉树是一种物理结构。
在中序线索树找结点后继的规律是:若其右标志为1,则右链为线索,指示其后继,否则遍历其右子树时访问的第一个结点(右子树最左下的结点)为其后继;找结点前驱的规律是:若其左标志为1,则左链为线索,指示其前驱,否则遍历左子树时最后访问的一个结点(左子树中最右下的结点)为其前驱。
在后序线索树中找到结点的后继分三种情况:
若结点是二叉树的根,则其后继为空;若结点是其双亲的右孩子,或是其双亲的左孩子且其双亲没有右子树,则其后继即为双亲结点;若结点是其双亲的左孩子,且其双亲有右子树,则其后继为双亲右子树上按后序遍历列出的第一个结点。
相关文章推荐
- iOS开发-一些面试算法总结
- iOS开发之银行卡校验规则(Luhn算法)
- 学习iOS、React Native、算法开发的建议
- iOS开发之Objective-c几种不同的随机数算法(arc4random,random,srandom)
- iOS开发之Objective-c的AES加密和解密算法的实现
- 嵌入式操作系统内核原理和开发(基于链表节点的内存分配算法)
- 算法 -- iOS开发用Objective_C / Swift3.0实现:直接插入排序 / 二分法插入排序 / 希尔排序
- 学习iOS、React Native、算法开发的建议
- iOS开发之Objective-c的AES加密和解密算法的实现
- iOS开发--图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序
- IOS开发-影院选座算法 限制产生孤座
- iOS开发UI基础—06九宫格算法示例
- AppNinja 开发手记2: QQ iOS版 表情加密解密算法
- 学习iOS、React Native、算法开发的建议
- 芒果iOS开发之常见算法总结
- ios开发——链表简单认识
- iOS开发之Objective-c的AES加密和解密算法的实现
- iOS开发 ----- C小型学生信息管理系统,单向链表
- iOS开发中的火星坐标系及各种坐标系转换算法
- 算法 -- iOS开发用Objective_C / Swift3.0实现:快速排序 / 冒泡排序 / 选择排序