黑马程序员技术交流社区

标题: 两种算法的分析 [打印本页]

作者: 张翼    时间: 2011-11-11 08:57
标题: 两种算法的分析
和顺序查找法相比,二分查找法有什么优势,使用二分查找法有什么优势?
作者: 齐国峰    时间: 2011-11-11 08:59
最大的优势就是速度快,查找的次数少,效率高。
作者: 刘一扬    时间: 2011-11-11 09:24
顺序查找法时间复杂度是O(n), 二分查找法O(n/2), 平均情况下,二分查找法的效率是顺序查找法的两倍
作者: せR3n、何必装纯    时间: 2011-11-11 10:21
二分查找

1、二分查找(Binary Search)
     二分查找又称折半查找,它是一种效率较高的查找方法。
     二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。

2、二分查找的基本思想
     二分查找的基本思想是:(设R[low..high]是当前的查找区间)
(1)首先确定该区间的中点位置:
               
(2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
     ①若R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]。
     ②类似地,若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1..n]中,即新的查找区间是右子表R[mid+1..n]。下一次查找是针对新的查找区间进行的。
     因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。

3、二分查找算法
    int BinSearch(SeqList R,KeyType K)
      { //在有序表R[1..n]中进行二分查找,成功时返回结点的位置,失败时返回零
        int low=1,high=n,mid; //置当前查找区间上、下界的初值
        while(low<=high){ //当前查找区间R[low..high]非空
          mid=(low+high)/2;
          if(R[mid].key==K) return mid; //查找成功返回
          if(R[mid].kdy>K)
             high=mid-1; //继续在R[low..mid-1]中查找
          else
             low=mid+1; //继续在R[mid+1..high]中查找
         }
        return 0; //当low>high时表示查找区间为空,查找失败
       } //BinSeareh

顺序查找(Sequential Search)

     在表的组织方式中,线性表是最简单的一种。顺序查找是一种最简单的查找方法。

1、顺序查找的基本思想
     基本思想是:从表的一端开始,顺序扫描线性表,依次将扫描到的结点关键宇和给定值K相比较。若当前扫描到的结点关键字与K相等,则查找成功;若扫描结束后,仍未找到关键字等于K的结点,则查找失败。

2、顺序查找的存储结构要求
  顺序查找方法既适用于线性表的顺序存储结构,也适用于线性表的链式存储结构(使用单链表作存储结构时,扫描必须从第一个结点开始)。

3、基于顺序结构的顺序查找算法
(1)类型说明
  typedef struct{
    KeyType key;
    InfoType otherinfo; //此类型依赖于应用
   }NodeType;
  typedef NodeType SeqList[n+1]; //0号单元用作哨兵

(2)具体算法
  int SeqSearch(Seqlist R,KeyType K)
    { //在顺序表R[1..n]中顺序查找关键字为K的结点,
      //成功时返回找到的结点位置,失败时返回0
      int i;
      R[0].key=K; //设置哨兵
      for(i=n;R[i].key!=K;i--); //从表后往前找
      return i; //若i为0,表示查找失败,否则R[i]是要找的结点
    } //SeqSearch
  注意:
     监视哨设在高端的顺序查找【参见练习】

(3)算法分析
① 算法中监视哨R[0]的作用
    为了在for循环中省去判定防止下标越界的条件i≥1,从而节省比较的时间。

②成功时的顺序查找的平均查找长度:
   
     在等概率情况下,pi=1/n(1≤i≤n),故成功的平均查找长度为
        (n+…+2+1)/n=(n+1)/2
即查找成功时的平均比较次数约为表长的一半。
     若K值不在表中,则须进行n+1次比较之后才能确定查找失败。



程序实例:

        #include "stdafx.h"

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>


/*二分查找*/
int bs(int data[],int dvalue,int length)
{  
  int low = 0;
  int high = length;
  int mid = 0;
  int mid_data = 0;
   
  while(low<=high)
  {
mid=(low+high)/2;
mid_data = data[mid];
if(dvalue == mid_data)
{
  return mid;
}
else if(dvalue > mid_data)
{
  low = mid + 1;
}
else
{
  high = mid - 1;
}
  }
  return -1;   
}  
/*顺序查找*/
int ss(int *data,int dvalue,int length)
{  
  int i;  
  // int l=len(data);  
  for(i=0;i<length;i++)
  {  
    // printf("%d/n",data[i]);  
    if(data[i]==dvalue)
{  
      return i;  
    }  
  }  
  return -1;  
}  
int main()
{   
  
int data[] = {0,2,69,300,500,569,700,789,800,963};

    int n = sizeof(data)/sizeof(data[0]);
//要查找的值  
int value=4;  
   
//顺序查找  
int s=ss(data,value,n);  
printf("%d/n",s);  
//二分查找      
int d=bs(data,value,n);  
printf("%d/n",d);  
   
  return 0;  
}

作者: 骚灵小情歌    时间: 2011-11-11 10:40
楼上每次回答都好猛- -烈




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2