数据--第48课 - 顺序表和有序表查找

本文深入探讨了数据结构中的查找技术,包括顺序查找、二分查找、插值查找及其实现方法。通过对比不同查找算法的效率,帮助读者理解在不同场景下选择合适查找策略的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第48课 - 顺序表和有序表查找

1. 顺序表查找

从线性表中的第一个(或最后一个)数据元素开始,逐个进行数据元素关键字和给定值的比较,若某个数据元素的关键字和给定值相等则查找成功;如果直到最后一个(或第一个)数据元素,其关键字和给定值都不等时,则查找失败。

 

2. 二分查找

基本思想。

首先将查找表进行排序。

取中间数据元素进行比较。

当给定值与中间数据元素的关键字相等时,查找成功。

当给定值小于中间元素时,在中间元素左区间进行二分查找。

当给定值大于中间元素时,在中间元素右区间进行二分查找。

当任意区间均无记录时,查找失败。

 

3. 二分查找进一步分析

(1)      二分查找的精髓:mid = (low + high) / 2

(2)      等量代换:mid = low + (high - low) / 2

(3)      扩展:设f(x) = ½,则:mid = low + f(x)(high - low)

(4)      f(x)的选择可以不只是常数,但必须满足:0 <= f(x) <= 1。

(5)      由于二分查找基于有序的线性表,因此对给定的查找值key,我们可以事先估计它的位置。

如:

key = 4

list = {1, 3, 4, 5, 6, 8, 10, 11, 13, 14, 15, 16}

 

4. 插值查找

根据要查找的关键字key与查找表中最大最小记录的关键字比较

后的查找方法,其核心为:

mid = low + f(key)(high - low)

f(x) = (x - a[low]) / (a[high] - a[low])

不同的f(x)的选取可以得到不同的查找算法。

 

5. 程序

OrderSearch.c

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

#define SIZE 20

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

 

void println(int array[], int len)

{

    int i = 0;

   

    for(i=0; i<len; i++)

    {

        printf("%d ", array[i]);

    }

   

    printf("\n");

}

 

void swap(int array[], int i, int j)

{

    int temp = array[i];

   

    array[i] = array[j];

   

    array[j] = temp;

}

 

void SelectionSort(int array[], int len) // O(n*n)

{

    int i = 0;

    int j = 0;

    int k = -1;

   

    for(i=0; i<len; i++)

    {

        k = i;

       

        for(j=i; j<len; j++)

        {

            if( array[j] < array[k] )

            {

                k = j;

            }

        }

       

        swap(array, i, k);

    }

}

 

int binary_search(int a[], int low, int high, int key) // O(logn)

{

    int ret = -1;

   

    if( low <= high )

    {

        int mid = (low + high) / 2;

       

        if( a[mid] == key )

        {

            ret = mid;

        }

        else if( key < a[mid] )

        {

            ret = binary_search(a, low, mid-1, key);

        }

        else if( key > a[mid] )

        {

            ret = binary_search(a, mid+1, high, key);

        }

    }

   

    return ret;

}

 

int binary_search_ex(int a[], int low, int high, int key) // O(logn)

{

    int ret = -1;

   

    while( low <= high )

    {

        int mid = (low + high) / 2;

       

        if( a[mid] == key )

        {

            ret = mid;

            break;

        }

        else if( key < a[mid] )

        {

            high = mid - 1;

        }

        else if( key > a[mid] )

        {

            low = mid + 1;

        }

    }

   

    return ret;

}

 

int interpolation_search(int a[], int low, int high, int key)

{

    int ret = -1;

   

    while( (low <= high) && (a[low] <= key) && (key <= a[high]) )

    {

        float fx = 1.0f * (key - a[low]) / (a[high] - a[low]);

        int mid = low + fx * (high - low);

       

        if( a[mid] == key )

        {

            ret = mid;

            break;

        }

        else if( key < a[mid] )

        {

            high = mid - 1;

        }

        else if( key > a[mid] )

        {

            low = mid + 1;

        }

    }

   

    return ret;

}

 

int main(int argc, char *argv[])

{

    int a[SIZE] = {0};

    int i = 0;

    int key = 0;

    int index = 0;

   

    srand((unsigned int)time(NULL));

   

    for(i=1; i<=SIZE; i++)

    {

        a[i] = rand() % 100;

    }

   

    key = 50;

   

    printf("Binary Search Demo\n");

    printf("Key: %d\n", key);

    printf("Array: \n");

   

    SelectionSort(a, SIZE);

   

    println(a, SIZE);

   

    index = interpolation_search(a, 0, SIZE-1, key);

   

    if( index > 0 )

    {

        printf("Success: a[%d] = %d\n", index, a[index]);

    }

    else

    {

        printf("Failed!\n");

    }

   

         return 0;

}

AnotherSearch.c

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

#define SIZE 20

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

 

void print_array(int a[], int begin, int end)

{

    int i = 0;

   

    for(i=begin; i<=end; i++)

    {

        printf("%d, ", a[i]);

    }

   

    printf("\n");

}

 

int another_search(int a[], int len, int key)

{

    int ret = len;

   

    a[0] = key;

   

    while( a[ret] != key )

    {

        ret--;

    }

   

    return ret;

}

 

int main(int argc, char *argv[])

{

    int a[SIZE + 1] = {0};

    int i = 0;

    int key = 0;

    int index = 0;

   

    srand((unsigned int)time(NULL));

   

    for(i=1; i<=SIZE; i++)

    {

        a[i] = rand() % 100;

    }

   

    key = rand() % 100;

   

    printf("Another Search Demo\n");

    printf("Key: %d\n", key);

    printf("Array: \n");

    print_array(a, 1, SIZE);

   

    index = another_search(a, SIZE, key);

   

    if( index > 0 )

    {

        printf("Success: a[%d] = %d\n", index, a[index]);

    }

    else

    {

        printf("Failed!\n");

    }

   

         return 0;

}

 

转载于:https://www.cnblogs.com/free-1122/p/11336101.html

当然,为了演示顺序查找折半查找的区别,我们可以分别为两个表编写C++程序: 首先,对于查找表1(顺序查找): ```cpp #include <iostream> #include <vector> std::vector<int> table1 = {8, 15, 19, 26, 33, 41, 47, 52, 64, 90}; // 顺序查找函数 int sequential_search(int* arr, int size, int target) { for (int i = 0; i < size; i++) { if (arr[i] == target) { return i + 1; // 返回目标值的索引加1,因为C++是从0开始计数的 } } return -1; // 未找到目标值 } int main() { int key = 41; int comparisons = sequential_search(&table1[0], table1.size(), key); std::cout << "查找key=" << key << " 的比较次数: " << comparisons << std::endl; return 0; } ``` 然后,对于查找表2(折半查找,假设数据已经预处理成升序,因为折半查找要求有序): ```cpp #include <iostream> #include <vector> std::vector<int> table2 = {12, 15, 20, 29, 33, 35, 48, 62, 76, 89}; // 假设已经排序 // 折半查找函数 int binary_search(int* arr, int left, int right, int target) { while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] == target) { return mid + 1; // 返回目标值的索引加1 } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; // 未找到目标值 } int main() { int key = 35; int comparisons = binary_search(&table2[0], 0, table2.size() - 1, key); std::cout << "查找key=" << key << " 的比较次数: " << comparisons << std::endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值