查找
根据某个给定关键字K,从集合R中找出关键字与K相同的记录
- 静态查找:集合中记录是固定的,没有插入和删除操作,只有查找
- 动态查找:集合中记录是动态变化的,除查找,还可能发生插入和删除
静态查找
顺序查找
int SequentialSearch(StaticTable *Tbl, ElementType K) {
int i;
for (int i = 0; i < Tbl->Length; i++) {
if (Tbl->Element[i] == K)
return i;
}
return -1;
}
顺序查找算法的时间复杂度为
二分查找(Binary Search)
假设n个数据元素的关键字满足有序(比如:小到大)
k_1 \le k_2 \le ... \le k_n
并且是连续存放(数组),那么可以进行二分查找
代码实现
int BinarySearch(StaticTale *Tbl, ElementType K) {
int left, right, mid, NotFound = -1;
left = 0; // 初始左边界
right = Tbl->Length - 1; // 初始右边界
while (left <= right) {
mid = (left + rigth) / 2; // 计算中间元素座标
if (k < Tbl->Element[mid]) // 调整右边界
right = mid - 1;
else if (k > Tbl->Element[mid]) // 调整左边界
left = mid + 1;
else
return mid; // 查找成功,返回下标
}
return NotFound; // 查找失败,返回-1
}
二分查找算法具有对数的时间复杂度
二分查找判定树
进行二分查找的时候,元素会构成一个二分查找判定树:
* 判定树上每个结点需要的查找次数刚好为该结点所在的层数
* 查找成功时查找次数不会超过判定树的深度
* n个结点的判定树深度为
树(Tree)
定义
n(n≥0) 个结点构成的有限集合- 当
n=0 时,称为空树 - 对于任一棵非空树
(n≥0) ,它具备以下性质:
- 树中有一个称为“根(Root)”的特殊结点,用r表示
- 其余结点可分为
m(m≥0) 个互不相交的有限集T1,T2,...,Tm ,其中每个集合本身又是一棵树,称为原来树的“子树(SubTree)” - 子树是不相交的
- 除了根结点外,每个结点有且仅有一个父节点
- 一棵
N 个结点的树有N−1 条边
基本术语
- 结点的度(Degree):结点的子树个数
- 树的度:树的所有结点中最大的度数
- 叶结点(Leaf):度为0的结点
- 父节点(Parent):有子树的结点是其子树的根结点的父结点
- 子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点。子结点也称孩子结点
- 兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点
- 路径和路径长度:从结点
n1 到nk 的路径为一个结点序列n1,n2,...,nk ,ni 是ni+1 的父结点。路径所包含边的个数为路径的长度 - 祖先结点(Ancestor):沿树根到某一结点路径上的所有结点都是这个结点的祖先结点
- 子孙结点(Descendant):某一结点的子树中所有结点是这个结点的子孙
- 结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1
- 树的深度(Depth):树中所有结点中的最大层次是这棵树的深度