数据结构之查找

一 查找概论

相关定义:

查找表(Search Table):是由同一类型的数据元素(或记录)构成的集合。

关键字(Key):是数据项中某个数据项的值,又称为键值,用它可以表示一个数据元素。也可以表示一个记录的某个数据项(字段),我们称为关键码。若此关键字可以唯一的标识一个记录,则称此关键字(Primary Key),对于不同的记录,其主关键字均不相同,主关键字所在的数据项称为主关键码。对于那些可以标识多个(或记录)的关键字,我们称为次关键字(Secondary Key),次关键字也可以理解为不以唯一标识一个数据元素(记录)的关键字,它对应的数据项就是次关键码。

查找:就是根据给定的某个值,在查找表中确定一个其主关键字等于给定值的数据元素(或记录)。

查找表的分类: 静态查找表,或者动态查找表。

静态查找表(只做查找操作的查找表)的主要操作是:
(1)查询某个“特定的”元素是否在查找表中。
(2)检索某个“特定的”数据元素和各种属性。

动态查找表:在查找过程中同时插入查找表中不存在 的数据元素,或者从查找表中删除已经存在的某个数据元素,动态查找表的操作主要操作是:
(1)查找的时候插入数据元素。
(2)查找的时候删除数据元素。	

二 顺序表查找

1.顺序查找

顺序查找又叫线性查找,是最基本的查找技术,它的查找过程是:从表中的第一个元素开始(或者最后一个元素开始),逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的纪律,如果直到最后一个(或第一个),其关键字和给定值都不相等时,则表中没有所查的记录,查找不成功。

2.顺序表查找算法

class Search{
	int sequential_Search(int[] a,int key){
			int i;
			for(i = 1;i<=a.length();i++){
				if(a[i] == key){
					return i;
				}
			}
			return 0;
		}
}

2.1 顺序查找表的优化
每次循环需要对i是否越界,即是否小于等于n做比较,可以设置一个哨兵,可以解决不需要每次让i与n做判断。

public class SequentialSearch {
    /**
     * 设置哨兵的顺序表优化
     * @param a
     * @param n
     * @param key
     * @return
     */
    int sequentialSearch2(int[] a,int n,int key){
        int i;
        a[0] = key;//将哨兵设置在0处,
        i = n;//循环从数组尾部开始
        while(a[i] != key){
            i--;
        }
        return i;//返回0则表示查找失败
    }
}

2.3 顺序查找表总结:

查找成功最好的情况下就在第一个位置就找到了,算法的时间复杂度就为O(1),最坏的情况下是在最后一个位置才找到,需要n比较,实际复杂度为O(n),查找不成功是需要n+1次比较,时间复杂度为O(n)。关键字在任何一个位置的概率是相同的,所以平均查找次数为(n+1)/2,最终的时间复杂度为n(n)。显然顺序查找技术是有很大的缺点,n很大的时候,查找效率极为低下,优点,这个算法十分的简单,对静态查找表的记录没有任何要求,在一些小型的数据查找时,是可以适用的。另外,也正是由于查找概率的不同,我们完全可以将容易查找的记录放在前面,而不常用的记录放置后面,效率就可以有很大的提升。

三 有序表的查找

3.1 折半查找

折半查找技术,又称为二分查找,它的前提是线性表中的记录必须是关键码有序(通常是从小到大有序),线性表必须采用
顺序存储。折半查找的基本思想是:在有序表中,去中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成
功,若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的
右半区继续查找。不断重复上述过程,知道查找成功,或所有查找区域无记录,查找失败为止。
public class BinarySearch {

    public static int binarySerarch(int[] a, int key){
        int low,high,mid;
        low = 0;
        high = a.length-1;

        while(low <= high){
            mid = (low + high) / 2;
            if(key < a[mid]){
                high = mid -1;
            }else if(key > a[mid]){
                low  = mid + 1;
            }else {
                return mid;
            }
        }
        return 0;
    }

    public static void main(String[] args) {
        int[] a = new int[]{0,1,16,24,35,47,59,62,73,88,99};
        int i = binarySerarch(a, 62);
        System.out.println(i);
    }
}

输出:

7

3.2 折半查找总结

对具有n个节点的完全二叉树的深度为log2n +1,向下取整加1,这里虽然折半查找不是完全二叉树,但是同样可以得出
最坏情况是查找到关键字或查找失败的次数为log2n+1;最终折半查找算法的时间复杂度为o(logn)。折半查找的前提条
件是需要有序表顺序存储。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值