Chinaunix首页 | 论坛 | 博客
  • 博客访问: 321527
  • 博文数量: 64
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1972
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-31 21:53
个人简介

文明之精神,野蛮之体魄。

文章分类
文章存档

2015年(4)

2013年(60)

我的朋友

分类: C/C++

2013-10-21 19:35:04

一、      顺序表和有序表查找

1.    顺序表查找

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

2.    代码实现

#include

#include

#include

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

#define SIZE 20

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 serach 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");

      }

     

}

3.    二分查找

基本思想

首先将查找表进行排序。

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

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

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

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

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

4.    二分查找实现

#include

#include

#include

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

#define SIZE 20

void print_array(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)

{

      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[k] > array[j]){

                      k = j;

                 }

           }

           swap(array,i,k);

      }

}

int Binary_search(int a[],int low,int high,int key)//递归

{

      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)//用循环代替递归

{

      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 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 = 0;i < SIZE;i++){

                 a[i] = rand() % 100;

      }

 

      SelectionSort(a,SIZE);   

      key = rand() % 100;

      printf("Binary serach demo:\n");

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

      printf("Array: \n");

      print_array(a,SIZE);

     

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

      if(index >= 0){

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

          

      }else{

           printf("Failed!\n");

      }

     

}

5.    二分查找进一步分析

二分查找的精髓

mid = (low + high) / 2

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

扩展:设f(x) = 1/2,则:mid = low + f(x) * (high – low)

问题:如何选择f(x)

f(x)的选择可以不只是常数,但必须满足:

0 <= f(x) <= 1

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

如:

key = 4

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

6.    插值查找

根据要查找的关键字key与查找表中的最大最小记录的关键字比较后的查找方法,其核心为:

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

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

7.    插值查找实现

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);

      printf("%d\n",a[mid]);

      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;

}

8.    小结

顺序查找比较土,但却是其他查找算法的基础。

二分查找基于有序的线性表,时间复杂度提高到O(log n)

二分查找可以根据需要进一步演变为插值查找。

阅读(1873) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~