0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

常见的查找算法汇总(含详细代码)2

jf_78858299 来源:阿Q正砖 作者:阿Q正砖 2023-04-24 17:20 次阅读

4、斐波那契查找

4.1、基本原理

斐波那契查找算法(Fibonacci Search Algorithm)是一种利用斐波那契数列长度的有序数组进行查找的算法。与二分查找不同,斐波那契查找每次的查找范围是斐波那契数列中的某一段,从而更加高效地进行查找。

具体来说,假设待查找的数组为arr,数组长度为n。斐波那契查找首先要确定一个斐波那契数列fib,满足fib[k] >= n,且fib[k-1] < n。然后根据当前查找范围的左右端点计算mid = left + fib[k-1],即查找范围中点的位置。如果arr[mid] == target,则查找成功;如果arr[mid] < target,则在mid的右侧继续查找;如果arr[mid] > target,则在mid的左侧继续查找。查找的过程类似于二分查找,只不过查找范围不是一半,而是根据斐波那契数列划分的一段。

斐波那契查找的优点是可以在O(log n)的时间内完成查找,比一般的线性查找O(n)和二分查找O(log n)更快。但是需要注意的是,斐波那契查找算法只适用于元素数量比较大、分布均匀的数组。对于元素数量较少或分布不均的数组,效率并不一定比其他算法高。

4.2、代码示例

方法一:

假设需要查找的元素为key,数组为arr,数组长度为n

#include 
#include 


// 斐波那契查找算法
int fib_search(int arr[], int n, int key) {
    // 初始化斐波那契数列
    int fib1 = 0;
    int fib2 = 1;
    int fibn = fib1 + fib2;


    // 找到斐波那契数列中第一个大于等于n的数
    while (fibn < n) {
        fib1 = fib2;
        fib2 = fibn;
        fibn = fib1 + fib2;
    }


    // 对数组进行扩展,使其长度为斐波那契数列中的某个数
    int *tmp = (int *)malloc(fibn * sizeof(int));
    for (int i = 0; i < n; i++) {
        tmp[i] = arr[i];
    }
    for (int i = n; i < fibn; i++) {
        tmp[i] = arr[n - 1];
    }


    // 开始查找
    int low = 0;
    int high = fibn - 1;
    int mid;
    while (low <= high) {
        // 计算当前中间位置
        mid = low + fib1 - 1;
        // 如果key比当前位置的值小,则在左侧继续查找
        if (key < tmp[mid]) {
            high = mid - 1;
            fibn = fib1;
            fib1 = fib2 - fib1;
            fib2 = fibn - fib1;
        }
        // 如果key比当前位置的值大,则在右侧继续查找
        else if (key > tmp[mid]) {
            low = mid + 1;
            fibn = fib2;
            fib1 = fib1 - fib2;
            fib2 = fibn - fib1;
        }
        // 找到了key
        else {
            // 如果当前位置小于n,则返回该位置,否则返回n-1
            if (mid < n) {
                return mid;
            } else {
                return n - 1;
            }
        }
    }


    // 没有找到key
    free(tmp);
    return -1;
}


// 测试代码
int main() {
    int arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
    int n = sizeof(arr) / sizeof(arr[0]);
    int key = 7;
    int index = fib_search(arr, n, key);
    if (index == -1) {
        printf("The key %d is not found.\\n", key);
    } else {
        printf("The key %d is found at index %d.\\n", key, index);
    }
    return 0;
}

注意:上述代码假设数组中的元素是按照从小到大的顺序排列的。如果数组中的元素是无序的,则需要先对数组进行排序,然后再进行斐波那契查找。

方法二:

#include 


// 获取斐波那契数列,n表示数列中第n个元素的值
int getFibonacci(int n) {
    if (n <= 0) return 0;
    if (n == 1) return 1;
    return getFibonacci(n-1) + getFibonacci(n-2);
}


// 斐波那契查找算法,a为有序数组,n为数组长度,key为要查找的元素
int fibonacciSearch(int a[], int n, int key) {
    int low = 0, high = n-1, k = 0, mid = 0;


    // 计算斐波那契数列中第k个数刚好大于n
    while (n > getFibonacci(k)-1) {
        k++;
    }


    // 将数组扩展到斐波那契数列中第k个数的长度
    int *temp = new int[getFibonacci(k)];
    for (int i = 0; i < n; i++) {
        temp[i] = a[i];
    }
    for (int i = n; i < getFibonacci(k); i++) {
        temp[i] = a[n-1];
    }


    // 二分查找
    while (low <= high) {
        mid = low + getFibonacci(k-1) - 1;
        if (key < temp[mid]) {
            high = mid - 1;
            k--;
        } else if (key > temp[mid]) {
            low = mid + 1;
            k -= 2;
        } else {
            if (mid < n) {
                return mid;
            } else {
                return n - 1;
            }
        }
    }
    delete [] temp;
    return -1;
}


int main() {
    int a[] = {1, 3, 5, 7, 9, 11, 13};
    int n = sizeof(a) / sizeof(a[0]);
    int key = 11;
    int pos = fibonacciSearch(a, n, key);
    if (pos >= 0) {
        printf("元素 %d 在数组中的位置为 %d\\n", key, pos);
    } else {
        printf("元素 %d 在数组中不存在\\n", key);
    }
    return 0;
}

在这段代码中,我们首先使用 getFibonacci 函数获取斐波那契数列中第k个数,然后将数组 a 扩展到斐波那契数列中第k个数的长度,这样做是为了保证数组长度大于等于斐波那契数列中第k个数,从而可以用斐波那契数列中的数作为分割点进行查找。最后,我们使用二分查找的方式进行查找,最终返回查找结果的下标或者-1表示查找失败。

5、哈希查找

5.1、基本原理

哈希查找是一种常用的查找算法,它的基本思想是将数据元素映射到一个固定的存储位置,从而实现快速的查找。哈希查找的基本原理是利用哈希函数将关键字映射到存储位置,当需要查找一个元素时,先通过哈希函数计算出该元素对应的存储位置,然后在该位置进行查找。

哈希函数是哈希查找的关键,它将关键字映射到一个存储位置。哈希函数应该具有良好的映射性能,能够均匀地将关键字分布到不同的存储位置上,这样可以避免冲突。冲突是指多个关键字映射到同一个存储位置上,这种情况下需要解决冲突。

哈希查找的注意事项包括以下几点:

  1. 哈希函数的设计应该具有良好的均匀性,能够尽可能避免冲突。
  2. 解决冲突的方法有很多,比如拉链法、开放地址法等。选择合适的冲突解决方法对哈希查找的效率影响很大。
  3. 哈希查找的效率取决于哈希函数的设计、冲突解决方法的选择以及负载因子等因素。
  4. 哈希表的大小应该合适,过大会造成空间浪费,过小会造成冲突增加。
  5. 哈希表的扩容和缩容是一个比较复杂的问题,需要根据实际情况进行考虑。

5.2、代码示例

下面是一个简单的哈希查找算法的代码示例,使用了线性探测法解决冲突。

#include 
#include 


#define TABLE_SIZE 13


typedef struct HashNode {
    int key;
    int value;
} HashNode;


typedef struct HashTable {
    HashNode *table[TABLE_SIZE];
} HashTable;


int hash(int key) {
    return key % TABLE_SIZE;
}


HashTable* createHashTable() {
    HashTable *hashTable = (HashTable*)malloc(sizeof(HashTable));
    for (int i = 0; i < TABLE_SIZE; i++) {
        hashTable->table[i] = NULL;
    }
    return hashTable;
}


void insert(HashTable *hashTable, int key, int value) {
    HashNode *node = (HashNode*)malloc(sizeof(HashNode));
    node->key = key;
    node->value = value;


    int index = hash(key);
    while (hashTable->table[index] != NULL) {
        index = (index + 1) % TABLE_SIZE;
    }
    hashTable->table[index] = node;
}


int search(HashTable *hashTable, int key) {
    int index = hash(key);
    while (hashTable->table[index] != NULL && hashTable->table[index]->key != key) {
        index = (index + 1) % TABLE_SIZE;
    }


    if (hashTable->table[index] == NULL) {
        return -1;
    } else {
        return hashTable->table[index]->value;
    }
}


void delete(HashTable *hashTable, int key) {
    int index = hash(key);
    while (hashTable->table[index] != NULL && hashTable->table[index]->key != key) {
        index = (index + 1) % TABLE_SIZE;
    }


    if (hashTable->table[index] != NULL) {
        free(hashTable->table[index]);
        hashTable->table[index] = NULL;
    }
}


int main() {
    HashTable *hashTable = createHashTable();
    insert(hashTable, 3, 100);
    insert(hashTable, 9, 200);
    insert(hashTable, 6, 300);
    insert(hashTable, 12, 400);


    int value = search(hashTable, 9);
    printf("Value: %d\\n", value);


    delete(hashTable, 9);


    value = search(hashTable, 9);
    printf("Value: %d\\n", value);


    return 0;
}

该代码实现了一个基于线性探测法的哈希查找算法,其中 HashTable 表示哈希表,HashNode 表示哈希表中的一个节点,包括键 key 和值 valuehash 函数用于计算哈希值,createHashTable 函数用于创建一个新的哈希表,insert 函数用于在哈希表中插入一个节点,search 函数用于在哈希表中查找指定的键,并返回对应的值,delete 函数用于从哈希表中删除指定的键。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6512

    浏览量

    87601
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66782
  • 查找算法
    +关注

    关注

    0

    文章

    6

    浏览量

    5510
收藏 人收藏

    评论

    相关推荐

    STM32 library、应用、源代码等资料 归档贴(查找方便)

    /jishu_423003_1_1.htmlSTM32F1,STM32F2,STM32F4 外设固件封装库 源码和libhttps://bbs.elecfans.com/jishu_419945_1_1.html芯达stm32源代码
    发表于 04-01 11:05

    PC电源常见问题汇总

    PC电源常见问题汇总,分享!
    发表于 04-29 16:03

    简单的查找算法

    ) returntemp->val;插入算法:first = newnode(key,val,first);在查找算法后面判断查找元素是否存在,然后多加一句新建节点。
    发表于 12-27 22:33

    基于Hash和二叉树的路由表查找算法

    基于Hash和二叉树的路由表查找算法 :提出了一种基于Hash和二又树的路由表查找算法,这一算法可以满足()C-768的转发要求,支持超过
    发表于 02-22 17:06 35次下载

    isis 7 professional_元件查找代码

    isis 7 professional元件查找代码有各总isis 7 professional元件的查找代码
    发表于 12-08 15:58 7次下载

    一种可变长查找表的单基快速傅里叶变换倒序算法

    为提高运算速度,降低查找表规模,在原有查找算法的基础上,提出一种单基快速傅里叶变换原址倒片算法。设计新的查找表构造
    发表于 02-24 11:31 0次下载

    详解C语言二分查找算法细节

    我相信对很多读者朋友来说,编写二分查找算法代码属于玄学编程,虽然看起来很简单,就是会出错,要么会漏个等号,要么少加个 1。
    的头像 发表于 06-22 09:05 2616次阅读
    详解C语言二分<b class='flag-5'>查找</b><b class='flag-5'>算法</b>细节

    超全分水岭算法汇总

    超全分水岭算法汇总
    发表于 10-08 10:27 0次下载

    电工接线常见案例彩色图汇总

    电工接线常见案例彩色图汇总
    发表于 11-18 15:44 53次下载

    A星路径规划算法完整代码资料汇总

    A星路径规划算法完整代码资料汇总
    发表于 12-03 17:16 11次下载

    汇总常见单片机原厂代码仓库,值得收藏

    汇总常见单片机原厂代码仓库,值得收藏
    发表于 12-03 16:06 9次下载
    <b class='flag-5'>汇总</b><b class='flag-5'>常见</b>单片机原厂<b class='flag-5'>代码</b>仓库,值得收藏

    常见查找算法汇总(含详细代码)1

    今天就把常见*查找算法也总结个通透, 还有详细代码解释, 真的是写完这篇感觉脑子已经不是自己的了,还希望大家好好利用。
    的头像 发表于 04-24 17:20 667次阅读
    <b class='flag-5'>常见</b>的<b class='flag-5'>查找</b><b class='flag-5'>算法</b><b class='flag-5'>汇总</b>(含<b class='flag-5'>详细</b><b class='flag-5'>代码</b>)1

    常见查找算法汇总(含详细代码)3

    今天就把常见****查找算法也总结个通透, 还有详细代码解释, 真的是写完这篇感觉脑子已经不是自己的了,还希望大家好好利用。
    的头像 发表于 04-24 17:20 489次阅读

    常见查找算法汇总(含详细代码)4

    今天就把常见****查找算法也总结个通透, 还有详细代码解释, 真的是写完这篇感觉脑子已经不是自己的了,还希望大家好好利用。
    的头像 发表于 04-24 17:20 388次阅读

    常见查找算法汇总(含详细代码)5

    今天就把常见****查找算法也总结个通透, 还有详细代码解释, 真的是写完这篇感觉脑子已经不是自己的了,还希望大家好好利用。
    的头像 发表于 04-24 17:20 592次阅读