zoukankan      html  css  js  c++  java
  • 数据结构(6)—— 查找

    写在前面

    查找这一节,和我大二第一次学时不同的是,多了B树和B+树的相关理论,但理解起来还可以。对这部分并没有进行代码实现,觉得没有必要。

    按照惯例,上一节地址:数据结构(5)—— 图

    顺序查找和折半查找

    注意点

    顺序查找不用说了,暴力for循环就完了。折半查找的思想理解起来十分简单,每次选取中间的点,把一个有序序列分成两部分,然后分别对比,不断缩小范围直到找到或找不到。直接看代码吧。

    代码

    /*
     * @Description: 顺序查找和折半查找
     * @version: 1.0
     * @Author: Liuge
     * @Date: 2021-07-27 20:07:39
     */
    
    #include<bits/stdc++.h>
    
    typedef struct{
        // 元素存储空间基址,0号留空当哨兵位,按实际长度分配
        int *elem;
        // 表的长度
        int tableLen;
    }SSTable;
    
    // 顺序查找
    int searchSeq(SSTable ST,int key){
        ST.elem[0] = key;
        int i=ST.tableLen;
        // 加入一个count来计算比较次数
        int count = 0;
        for(;ST.elem[i] != key;--i,count++);
        printf("顺序查找中比较了:%d 次
    ",count);
        return i;
    }
    
    // 折半查找 升序的查找
    int binarySearch(SSTable L,int key){
        // 定义上下限
        int low = 1;
        int high = L.tableLen;
        int mid;
        // 同样定义一个count计算比较次数
        int count = 0;
        while(low <= high){
            mid = (low + high) / 2;
            if(L.elem[mid] == key){
                count++;
                printf("折半查找中比较了:%d 次
    ",count);
                return mid;
            }else if(L.elem[mid] > key){
                count++;
                high = mid -1;
            }else{
                count++;
                low = mid + 1;
            }
            
        }
        printf("折半查找中比较了:%d
    ",count);
        return -1;
    }
    
    // 初始化
    void initST(SSTable &ST,int length){
        ST.tableLen = length;
        ST.elem = (int *)malloc(sizeof(int) * (ST.tableLen) + 1);
        printf("输入表中的数据元素:
    ");
        for (int i=1; i<=length; i++) {
            scanf("%d",&ST.elem[i]);
        }
    }
    
    // 主函数测试
    int main(){
        SSTable ST;
        initST(ST,5);
        int index = searchSeq(ST,2);
        if(index != 0){
            printf("顺序查找成功!下标为:%d
    ",index);
        }else{
            printf("顺序查找失败!顺序表中不存在该元素!
    ");
        }
        int index2 = binarySearch(ST,2);
        if(index2 != -1){
            printf("折半查找成功!下标为:%d
    ",index2);
        }else{
            printf("折半查找失败!顺序表中不存在该元素!
    ");
        }
    }
    

    哈希(散列)查找

    注意点

    与之前的查找算法不同的是,哈希查找首先需要构建一个哈希表,而在哈希表的构建过程中不可避免的会产生冲突,所以哈希表的核心是如何解决冲突。这里实现采用了最简单的一种方法:开放定址法里的线性探测法。这种方式是我们哈希查找最简单也是最常考的一种方式了,因此做了实现。所谓线性探测法,就是指如果这个区域发生了冲突,那就顺序往后看哪个地方为空就插入到哪里。非常好理解的思想,直接看代码实现。

    代码

    /*
     * @Description: 哈希查找,用线性探测法避免冲突
     * @version: 1.0
     * @Author: Liuge
     * @Date: 2021-07-30 20:27:39
     */
    #include<bits/stdc++.h>
    typedef struct {
        // 存放关键值
    	int key;
        // 存放所占位置 
    	int id;
        // 存放查找这个数据的查找次数 
    	int num;
    }Hash;
    
    int getRand() {   
        // 设置随机数范围1-100            
    	return rand() % 100 + 1;
    }
    // 创建Hash表
    void createHash(Hash H[]) {    
        // 以系统时间为种子                
    	srand((unsigned)time(NULL)); 
    	for (int i = 0; i < 19; i++){
            // 全部初始化为-1 
    		H[i].id = -1;
        }
    	int temp,flag=1,count=0;
        // Hash表储存14个数
    	for (int i = 1; i <= 14; i++) { 
    		count = 0;
            // 用随机数生成关键字值
    		temp = getRand();
            printf("第%d个数:%d
    ",i,temp);
    		int k = temp % 14;
    		count++;
    		while (flag) {
    			if (H[k].id == -1)
    			{
    				H[k].id = i;
    				H[k].key = temp;
    				H[k].num = count;
    				break;
    			}
    			// 如果冲突,则通过线性探测法寻找下一个位置 
    			else {
    				k = (k+1)%19;
    				count++;
    			}
    		}
    	}
    }
    int main() {
        // 创建表长为19个元素的Hash表
    	Hash H[18];                         
    	createHash(H);
    	printf("*****线性探测法处理冲突*****
    ");
    	double sum=0;
    	for (int i = 0; i < 19; i++) {
    		if (H[i].id != -1) {
                printf("%d   ",H[i].key);
    			sum += H[i].num;
    		}
    	}
        printf("
    ");
    	printf("插入时总比较次数:%0.0f
    ",sum);
        printf("平均查找长度:%.2f
    ",sum / 14);
    	return 0;
    }
    

    总结

    总的来说,这章内容并不算很多。最难的地方个人感觉就是B树和B+树那块了,二轮的时候好好做做。

  • 相关阅读:
    升级python2.7, 实现python2.7与python3并存

    JDK一键部署, 新添加进度条
    银行分类概述
    个人银行结算账户类别
    银联刷卡POS机冲正
    银行怎样处理坏账和贷款展期
    数据加解密和数据签名验签
    一行三会/首批试点民营银行
    前端base64加密
  • 原文地址:https://www.cnblogs.com/wushenjiang/p/15081592.html
Copyright © 2011-2022 走看看