静态查找-树的引子 代码实现 C语言 MOOC学习笔记#1
一、顺序查找
Typedef struct LNode* List;
struct LNode{
ElementType Element[MAXSIZE];
int Length;
};
int SequentialSearch(List Tbl,ElementType K){
int i;
Tbl->Element[0]=K; //set a sentinal
for (i=Tbl->Length;Tbl->Element[i]!=K;i--);
return i;
}
//return the index of K, or return 0 if K is not in the list
理解:
- List是指向LNode这个struct的一个指针,LNode中包含一个数组和数组的长度
- 对于Tbl,我们从数组的尾部往上开始读,查找K
- 哨兵思想:在Tbl[0]的位置放置哨兵K。故记得储存数据的时候[0]处不要放置数据。
- 时间复杂度为O(n)
二、二分查找(Binary Search)
1. 应用二分查找的先决条件
(1)数据存放在数组中,而不是链表
(2)数组按升序/降序排列
2. 基本思路
(1)应用两个边界,left和right,一个mid
(2)不断移动指针,查找结束的边界为:找到了目的元素,或者,right<left
3. 代码实现
int BinarySearch(List Tbl,ElementType K){
int left,right,mid,NoFound=-1;
left=1; //Initialize the left boundary
right=Tbl->right //Initialize the right boundary
while(left<=right){
mid=(left+right)/2; //get the index of mid
if(K<Tbl->Element[mid]) {right=mid-1;}
// move the right boundary
else if (K>Tbl->Element[mid]) {left=mid+1;}
// move the left boundary
else return mid;
// K is found
}
return NotFound;
}
注意事项:
(1)c程序中做除法的时候,得到的整数结果是直接舍去小数部分
(2)如果移动边界的时候直接=mid,而不是mid+1或者mid-1,会产生错误:
left或者right可能会跟mid重合,导致产生死循环出不来
(3)时间复杂度为O(logn)
4. 二分查找与树的联系
(1)先排序,使数据有序化
(2)从第1次的mid作为root开始,每次向下的child都为左右两边可能的mid。
特点:
(1)判定树上每个结点需要的查找次数正好为该节点所在的层数
(2)查找成功的时候查找次数不会超过判定树的深度
(3)n个结点判定树的深度为[log2n]+1
查找树的优点:
更有利于动态查找问题