数据结构C语言版折半查找

  1. /*  
  2.     名称:折半查找   
  3.     语言:数据结构C语言版   
  4.     编译环境:VC++ 6.0  
  5.     日期: 2014-3-26   
  6. */  
  7.   
  8. #include <stdio.h>  
  9. #include <malloc.h>  
  10. #include <windows.h>  
  11.   
  12.   
  13. #define N 11 // 数据元素个数   
  14.   
  15. typedef int KeyType; // 设关键字域为整型   
  16.   
  17. typedef struct // 数据元素类型   
  18. {  
  19.     KeyType key;    // 关键字域   
  20.     int others;     // 其它部分   
  21.  }ElemType;  
  22.   
  23.   
  24. // Search_Seq.h 静态查找表的顺序存储结构   
  25. typedef struct  
  26. {  
  27.     // 数据元素存储空间基址,建表时按实际长度分配,0号单元留空  
  28.     ElemType *elem;  
  29.     int length; // 表长度   
  30. }SSTable;  
  31.   
  32. ElemType r[N]={  
  33.     {05,1},{13,2},{19,3},{21,4},  
  34.     {37,5},{56,6},{64,7},{75,8},  
  35.     {80,9},{88,10},{92,11}  
  36. };  // 数据元素(以教科书P219的数据为例),全局变量   
  37.   
  38.   
  39. // 静态查找表(顺序表和有序表)的基本操作(7个)   
  40.   
  41. // 构造一个含n个数据元素的静态顺序查找表ST(数据来自全局数组r)   
  42. int Creat_Seq(SSTable *ST,int n)  
  43. {   
  44.     int i;  
  45.     (*ST).elem = (ElemType *)calloc(n+1, sizeof(ElemType));   
  46.     // 动态生成n+1个数据元素空间(0号单元不用)   
  47.     if(!(*ST).elem)  
  48.         return 0;  
  49.     for( i = 1; i <= n; i++)  
  50.         *((*ST).elem+i) = r[i-1]; // 将全局数组r的值依次赋给ST   
  51.     (*ST).length = n;  
  52.     return 1;  
  53. }  
  54.   
  55. // 重建静态查找表为按关键字非降序排序   
  56. void Ascend(SSTable *ST)  
  57. {     
  58.     int i, j, k;  
  59.     for(i = 1; i < (*ST).length; i++)  
  60.     {  
  61.         k = i;  
  62.         (*ST).elem[0] = (*ST).elem[i]; // 待比较值存[0]单元   
  63.         for(j = i+1; j <= (*ST).length; j++) //从中找到第i小的值  
  64.             if ((*ST).elem[j].key < (*ST).elem[0].key)  
  65.             {  
  66.                 k=j;  
  67.                 (*ST).elem[0]=(*ST).elem[j];  
  68.             }  
  69.         if(k != i) // 有更小的值则交换   
  70.         {  
  71.             (*ST).elem[k]=(*ST).elem[i];  
  72.             (*ST).elem[i]=(*ST).elem[0];  
  73.         }  
  74.     }  
  75. }  
  76.   
  77. // 构造一个含n个数据元素的静态按关键字非降序查找表ST,  
  78. // 数据来自全局数组r   
  79. int Creat_Ord(SSTable *ST,int n)  
  80. {  
  81.     int f;  
  82.     f = Creat_Seq(ST,n);    //构建一个静态表  
  83.     if( f ) //静态表存在,则对其进行重建  
  84.         Ascend(ST);  
  85.     return f;  
  86. }  
  87.   
  88. //  销毁表ST   
  89. int Destroy(SSTable *ST)  
  90. {   
  91.     free((*ST).elem);  
  92.     (*ST).elem = NULL;  
  93.     (*ST).length = 0;  
  94.   
  95.     return 1;  
  96. }  
  97.   
  98. // 算法9.2 P220   
  99. // 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数  
  100. // 值为该元素在表中的位置,否则为0。   
  101. int Search_Bin(SSTable ST,KeyType key)  
  102. {     
  103.     int low, high, mid;  
  104.     low = 1; // 置区间初值   
  105.     high = ST.length;  
  106.     while(low <= high)  
  107.     {  
  108.         mid = (low + high) / 2;  
  109.         if(key == ST.elem[mid].key)  // 找到待查元素   
  110.             return mid;  
  111.         else if(key < ST.elem[mid].key)  
  112.             high = mid - 1;     // 继续在前半区间进行查找   
  113.         else  
  114.             low = mid + 1;      // 继续在后半区间进行查找   
  115.     }  
  116.     return 0; // 顺序表中不存在待查元素   
  117. }  
  118.   
  119. // 按顺序对ST的每个元素调用函数Visit()一次且仅一次。  
  120. int Traverse(SSTable ST,void(*Visit)(ElemType))  
  121. {     
  122.     ElemType *p;  
  123.     int i;  
  124.       
  125.     p = ++ST.elem; // p指向第一个元素,第0个元素没有用   
  126.     for(i = 1; i <= ST.length; i++)  
  127.         Visit( *p++ );  
  128.       
  129.     return 1;  
  130. }  
  131.   
  132. void print(ElemType c) // Traverse()调用的函数   
  133. {  
  134.     printf("(%d %d) ", c.key, c.others);  
  135. }  
  136.   
  137. int main()  
  138. {  
  139.     SSTable st;  
  140.     int i;  
  141.     KeyType s;  
  142.       
  143.     Creat_Ord(&st, N);  // 由全局数组产生非降序静态查找表st   
  144.     Traverse(st,print); // 顺序输出非降序静态查找表st   
  145.   
  146.     printf("\n请输入待查找值的关键字: ");  
  147.     scanf("%d", &s);  
  148.     i = Search_Bin(st, s); // 折半查找有序表   
  149.     if( i )  
  150.         print(st.elem[i]);  
  151.     else  
  152.         printf("没找到.\n");  
  153.   
  154.     Destroy(&st);  
  155.     system("pause");  
  156.     return 0;  
  157. }  
  158.   
  159. /*  
  160. 输出效果:  
  161.   
  162. (5 1) (13 2) (19 3) (21 4) (37 5) (56 6) (64 7) (75 8) (80 9) (88 10) (92 11)  
  163. 请输入待查找值的关键字: 75  
  164. (75 8) 请按任意键继续. . .   
  165.   
  166. */   

运行结果如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值