顺序查找法:
顺序查找方法既适用于线性表的顺序存储结构,又适用千线性表的链式存储结构。下面只介 绍以顺序表作为存储结构时实现的顺序查找算法。
查找的基本概念:
查找:在数据集合中寻找满足某种条件的数据元素的过程称为查找
查找表:用于查找的数据集合称为查找表
常见操作:①查询符合条件的数据元素
②插入、删除数据元素
静态查找表:若一个查找表的操作只涉及查找操作,则无需动态地修改查找表,此类称为静态查找表
顺序查找与折半查找
顺序查找的算法思想:①从线性表的一端开始,逐个检查关键字是否满足给定的条件
②若查找到某个元素的关键字满足给定条件,则查找成功,返回该元素在线性表中的位置③若已经查找到表的另一端,但还没有找到符合给定条件的元素,则返回查找失败
相关算法事项:此实现中引入“哨兵”
typedef struct{
ElemType *elem; // 动态数组基址
int TableLen // 表的长度
}SSTable
int Search_Seq(SSTable ST,ElemType key){
ST.elem[0]= key // 引入哨兵
for(int i = ST.TableLen;key != ST.elem[0];--i) // 从后往前找
return i; // 若查找成功,则返回元素下标;若查找失败,返回0
}
上述算法中,将ST.elem[0]称为哨兵,引入它的目的是使得Search_Seq内的循环不必判断数组是否会越界。
查找i元素的次数为:n-i+1
查找失败次数:n+1
算法时间复杂度为 O(n)。
顺序查找的优点是:算法简单, 对表结构无任何要求,既适用于 顺序结构, 也适用千链式结 构, 无论记录是否按关键字有序均可应用。其缺点是: 平均查找长度较大, 查找效率较低, 所以 当n很大时, 不宜采用顺序查找。
折半查找法---又称二分查找,它仅适用于有序的顺序表
折半查找(Binary Searh) c 也称二分查找,它是一种效率较高的查找方法。但是,折半查找 要求线性表必须采用顺序存储结构, 而且表中元素按关键字有序排列。在下面及后续的讨论中, 均假设有序表是递增有序的。
基本思想:①首先将给定值key与表中中间位置的元素比较,若相等,则查找成功,返回该元素的存储位置 ② 若不等,则所需要查找的元素只能在中间元素以外的前半部分或后半部分。重复上面的步骤,直到找到为止,或确定表中没有所需要查找的元素,则查找不成功,返回查找失败的信息。
算法实现如下:
int Search_Bin(SSTalbe ST,ElemType key){
int low=1,high = ST.length; // 定义初始位置为1,表尾位置为表的长度
int mid; //定义中间值
while(low<=high) { //定义若满足low<=high 条件则表示满足执行的条件
mid = (low+high)/2 //进行折半取整,便于后续是采用前半部分查找或后半部分查找提供条件
if(ST.elem[mid] == key) return mid;
else if(key<ST.elem[mid]) high = mid - 1 //从前半部分继续查找
else low = mid+1 // 从后半部分继续查找
}
return -1; // 查找失败返回-1;
}
当折半查找算法选取中间节点时,既可以采取向下取整,又可以采取向上取整。但每次查找的取证方式必须相同。
【算法步骤】
①置查找区间初值,low为1,high为表长。
②当low小于等于high时, 循环执行以下操作:
1)mid取值为low和high的中间值;
2)将给定值key与中间位置记录的关键字进行比较,若相等则查找成功,返回中间位置mid
3)若不相等则利用中间位置记录将表对分成前、后两个子表 。如果key比中间位置记录 的关键字小,则 high取为mid-1 , 否则 low取为mid+1。
③ 循环结束,说明查找区间为空,则查找失败,返回0。
【算法分析】 折半查找过程可用二叉树来描述。树中每一结点对应表中一个记录,但结点值 不是记录的关 键字 ,而是记录在表中的位置序号 。把当前查找区间的中间位置作为根, 左子表和右子表分别作 为根的左子树和右子树,由此得到的二叉树称为折半查找的判定树。