目录python
客观世界中许多事物存在层次关系算法
其中,人类社会家谱以下图所示:数组
经过上述所说的分层次组织,可以使咱们在数据的管理上有更高的效率!那么,对于数据管理的基本操做——查找,咱们如何实现有效率的查找呢?数据结构
查找:根据某个给定关键字K,从集合R中找出关键字与K相同的记录spa
静态查找:集合中记录是固定的,即对集合的操做没有插入和删除,只有查找3d
动态查找:集合中记录是动态变化的,即对集合的操做既有查找,还可能发生插入和删除(动态查找不在咱们考虑范围内)指针
/* c语言实现 */ int SequentialSearch (StaticTable *Tbl, ElementType K) { // 在表Tbl[1]~Tb1[n]中查找关键字为K的数据元素 int i; Tbl->Element[0] = K; // 创建哨兵,即没找到能够返回哨兵的索引0表示未找到 for (i = Tbl->Length; Tbl->Element[i] != K; i--); // 查找成功返回所在单元下标;不成功放回0 return i; }
顺序查找算法的时间复杂度为O(n)code
假设n个数据元素的关键字知足有序(好比:小到大),即\(k_1<k_2<\cdots<k_n\),而且是连续存放(数组),那么能够进行二分查找。blog
例:假设有13个数据元素,按关键字由小到大顺序存放。二分查找关键字为444的数据元素过程以下图:索引
仍然以上面13个数据元素构成的有序线性表为例,二分查找关键字为43的数据元素以下图:
/* c语言实现 */ int BinarySearch (StaticTable *Tbl, ElementType K) { // 在表中Tbl中查找关键字为K的数据元素 int left, right, mid, NoFound = -1; left = 1; // 初始左边界 right = Tbl->Length; // 初始右边界 while (left <= right) { mid = (left + right) / 2; // 计算中间元素坐标 if (K < Tbl->Element[mid]) right = mid - 1; // 调整右边界 else if (K > Tbl->Element[mid]) left = mid + 1; // 调整左边界 else return mid; // 查找成功,返回数据元素的下标 } return NotFound; // 查找不成功,返回-1 }
# python语言实现 def binary_chop(alist, data): n = len(alist) first = 0 last = n - 1 while first <= last: mid = (last + first) // 2 if alist[mid] > data: last = mid - 1 elif alist[mid] < data: first = mid + 1 else: return True return False
二分查找算法具备对数的时间复杂度O(logN)
二分查找算法虽然解决了查找的时间复杂度问题,可是对于数据的插入和删除确是O(n)的,所以有没有一种数据结构,既能够减小数据查找的时间复杂度,又能够减小数据的插入和删除的复杂度呢?
除了使用上述两个方法进行关键字的查找,咱们还能够经过二叉树这种数据结构完成关键字的查找。
从上图能够看出,若是咱们须要寻找数字8,能够经过如下4步实现(可能看不懂,将来会看得懂):
树(Tree):\(n(n\geq{0})\)个结点构成的有限集合。
牢记树有如下3个特性:
兄弟结点(Sibling):具备同一父结点的各结点彼此是兄弟结点
路径和路径长度:从结点\(n_1\)到\(n_k\)的路径为一个结点序列\(n_1 , n_2 ,\cdots, n_k\) , \(n_i\)是\(n_{i+1}\)的父结点。路径所包含边的个数为路径的长度
子孙结点(Descendant):某一结点的子树中的全部结点是这个结点的子孙
结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1
树的深度(Depth):树中全部结点中的最大层次是这棵树的深度
上图所示树的链表表示法有很大的缺陷,假设树的深度很是大,而且不能保证全部树的子结点都有3个,那么会形成很大程度的浪费。
为了解决树的普通链表表示会有空间的浪费的缺陷,咱们能够把链表的指针设置两个连接,一个连接指向儿子结点,另外一个连接指向兄弟结点,以下图所示:
上图所示的树的表示方法,已经足够完美了,可是若是咱们把链表表示的树旋转45°角,会发现以下图所示:
通过45°角的旋转,咱们会发现一颗二叉树(一个结点至多拥有2个子结点的树),也就是说最普通的树其实能够经过二叉树表示,也就是说咱们只要把二叉树研究透了,咱们即研究透了树。