C语言数据结构之 折半查找实例详解

数据结构 折半查找

实例代码:

/*
  名称:折半查找
  语言:数据结构C语言版
  编译环境:VC++ 6.0
  日期: 2014-3-26
*/ 

#include <stdio.h>
#include <malloc.h>
#include <windows.h> 

#define N 11 // 数据元素个数  

typedef int KeyType; // 设关键字域为整型  

typedef struct // 数据元素类型
{
  KeyType key;  // 关键字域
  int others;   // 其它部分
 }ElemType; 

// Search_Seq.h 静态查找表的顺序存储结构
typedef struct
{
  // 数据元素存储空间基址,建表时按实际长度分配,0号单元留空
  ElemType *elem;
  int length; // 表长度
}SSTable; 

ElemType r[N]={
  {05,1},{13,2},{19,3},{21,4},
  {37,5},{56,6},{64,7},{75,8},
  {80,9},{88,10},{92,11}
}; // 数据元素(以教科书P219的数据为例),全局变量  

// 静态查找表(顺序表和有序表)的基本操作(7个)  

// 构造一个含n个数据元素的静态顺序查找表ST(数据来自全局数组r)
int Creat_Seq(SSTable *ST,int n)
{
  int i;
  (*ST).elem = (ElemType *)calloc(n+1, sizeof(ElemType));
  // 动态生成n+1个数据元素空间(0号单元不用)
  if(!(*ST).elem)
    return 0;
  for( i = 1; i <= n; i++)
    *((*ST).elem+i) = r[i-1]; // 将全局数组r的值依次赋给ST
  (*ST).length = n;
  return 1;
} 

// 重建静态查找表为按关键字非降序排序
void Ascend(SSTable *ST)
{
  int i, j, k;
  for(i = 1; i < (*ST).length; i++)
  {
    k = i;
    (*ST).elem[0] = (*ST).elem[i]; // 待比较值存[0]单元
    for(j = i+1; j <= (*ST).length; j++) //从中找到第i小的值
      if ((*ST).elem[j].key < (*ST).elem[0].key)
      {
        k=j;
        (*ST).elem[0]=(*ST).elem[j];
      }
    if(k != i) // 有更小的值则交换
    {
      (*ST).elem[k]=(*ST).elem[i];
      (*ST).elem[i]=(*ST).elem[0];
    }
  }
} 

// 构造一个含n个数据元素的静态按关键字非降序查找表ST,
// 数据来自全局数组r
int Creat_Ord(SSTable *ST,int n)
{
  int f;
  f = Creat_Seq(ST,n);  //构建一个静态表
  if( f ) //静态表存在,则对其进行重建
    Ascend(ST);
  return f;
} 

// 销毁表ST
int Destroy(SSTable *ST)
{
  free((*ST).elem);
  (*ST).elem = NULL;
  (*ST).length = 0; 

  return 1;
} 

// 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数
// 值为该元素在表中的位置,否则为0。
int Search_Bin(SSTable ST,KeyType key)
{
  int low, high, mid;
  low = 1; // 置区间初值
  high = ST.length;
  while(low <= high)
  {
    mid = (low + high) / 2;
    if(key == ST.elem[mid].key) // 找到待查元素
      return mid;
    else if(key < ST.elem[mid].key)
      high = mid - 1;   // 继续在前半区间进行查找
    else
      low = mid + 1;   // 继续在后半区间进行查找
  }
  return 0; // 顺序表中不存在待查元素
} 

// 按顺序对ST的每个元素调用函数Visit()一次且仅一次。
int Traverse(SSTable ST,void(*Visit)(ElemType))
{
  ElemType *p;
  int i; 

  p = ++ST.elem; // p指向第一个元素,第0个元素没有用
  for(i = 1; i <= ST.length; i++)
    Visit( *p++ ); 

  return 1;
} 

void print(ElemType c) // Traverse()调用的函数
{
  printf("(%d %d) ", c.key, c.others);
} 

int main()
{
  SSTable st;
  int i;
  KeyType s; 

  Creat_Ord(&st, N); // 由全局数组产生非降序静态查找表st
  Traverse(st,print); // 顺序输出非降序静态查找表st  

  printf("\n请输入待查找值的关键字: ");
  scanf("%d", &s);
  i = Search_Bin(st, s); // 折半查找有序表
  if( i )
    print(st.elem[i]);
  else
    printf("没找到.\n"); 

  Destroy(&st);
  system("pause");
  return 0;
} 

/*
输出效果: 

(5 1) (13 2) (19 3) (21 4) (37 5) (56 6) (64 7) (75 8) (80 9) (88 10) (92 11)
请输入待查找值的关键字: 75
(75 8) 请按任意键继续. . .  

*/

运行结果如下:

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • C语言数据结构树的双亲表示法实例详解

    1.树的双亲表示法: 树的双亲表示法 2./* bo6-4.c 树的双亲表存储(存储结构由c6-4.h定义)的基本操作(14个) */ Status InitTree(PTree *T) { /* 操作结果: 构造空树T */ (*T).n=0; return OK; } void DestroyTree() { /* 由于PTree是定长类型,无法销毁 */ } typedef struct { int num; TElemType name; }QElemType; /* 定义队列元素类型

  • 详解C语言函数返回值解析

    详解C语言函数返回值解析 程序一: int main() { int *p; int i; int*fun(void); p=fun(); for(i=0;i<3;i++) { printf("%d\n",*p); p++; } return 0; }; int* fun(void) { static int str[]={1,2,3,4,5}; int*q=str; return q; } //不能正确返回 虽然str是在动态变量区,而该动态变量是局部的,函数结束时不保留的.

  • C语言用栈实现十进制转换为二进制的方法示例

    本文实例讲述了C语言用栈实现十进制转换为二进制的方法.分享给大家供大家参考,具体如下: #include<stdio.h> #include<malloc.h> #include<math.h> #include<string.h> #include "process.h" #define SIZE 100 #define STACKINCREMENT 10 #define OK 1 #define ERROR 0 #define TRU

  • C语言中双向链表和双向循环链表详解

    双向链表和双向循环链表 和单向链表相比,多了一个前驱结点.如果他为空,那么next和prior都指向自己.而对于双循环链表,只需要最后一个元素的next指向head->next,head->next的prior指向最后一个节点即可. 插入操作 新节点s插入链表,s->next给p结点,s->prior给p->prior,然后,p->prior->next指向s,p->prior再指向s.顺序需要注意 s->next = p; s->prior =

  • C语言实现图的搜索算法示例

    本文实例讲述了C语言实现图的搜索算法.分享给大家供大家参考,具体如下: 在游戏中,常常遇到路径规划问题,用到图的相关算法,我们以简单图来学习. 图通常有两种表示方式,矩阵和邻接表.矩阵表示简单,运算快,但当矩阵是稀疏矩阵的时候就存在空间浪费的问题,并且效率也会下降,而邻接表节约空间,并且由于边是连续访问,时间效率也比较高.在本文中,我们将以邻接表来表示图. #include<queue> #include<stack> using namespace std; struct SE{

  • C语言数据结构算法之实现快速傅立叶变换

    C语言数据结构算法之实现快速傅立叶变换 本实例将实现二维快速傅立叶变换,同时也将借此实例学习用c语言实现矩阵的基本操作.复数的基本掾作,复习所学过的动态内存分配.文件操作.结构指针的函数调用等内容. 很久以来,傅立叶变换一直是许多领域,如线性系统.光学.概率论.量子物理.天线.数字图像处理和信号分析等的一个基本分析工具,但是即便使用计算速度惊人的计算机计算离散傅立叶变换所花费的时间也常常是难以接受的,因此导致了快速傅立叶变换(FFT)的产生. 本实例将对一个二维数组进行正.反快速傅立叶变换.正傅

  • C语言数据结构之 折半查找实例详解

    数据结构 折半查找 实例代码: /* 名称:折半查找 语言:数据结构C语言版 编译环境:VC++ 6.0 日期: 2014-3-26 */ #include <stdio.h> #include <malloc.h> #include <windows.h> #define N 11 // 数据元素个数 typedef int KeyType; // 设关键字域为整型 typedef struct // 数据元素类型 { KeyType key; // 关键字域 int

  • C语言数据结构 链表与归并排序实例详解

    C语言数据结构 链表与归并排序实例详解 归并排序适合于对链表进行原址排序,即只改变指针的连接方式,不交换链表结点的内容. 归并排序的基本思想是分治法:先把一个链表分割成只有一个节点的链表,然后按照一定顺序.自底向上合并相邻的两个链表. 只要保证各种大小的子链表是有序的,那么最后返回的链表就一定是有序的. 归并排序分为分割和合并两个子过程.分割是用递归的方法,把链表对半分割成两个子链表:合并是在递归返回(回朔)的时候,把两个有序链表合并成一个有序链表. (注意:只有一个节点的链表一定是有序的) 这

  • C语言 数据结构之中序二叉树实例详解

    C语言数据结构 中序二叉树 前言: 线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题.它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点.两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间. 要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码): left leftTag data rightTag right 说明: 1.       leftTag=false时,表示left

  • C语言树状数组的实例详解

    C语言树状数组的实例详解 最近学了树状数组,给我的感觉就是 这个数据结构好神奇啊^_^ 首先她的常数比线段树小,其次她的实现复杂度也远低于线段树 (并没有黑线段树的意思=-=) 所以熟练掌握她是非常有必要的.. 关于树状数组的基础知识与原理网上一搜一大堆,我就不赘述了,就谈一些树状数组的应用好了 1,单点修改,求区间和 #define lowbit(x) (x&-x) // 设 x 的末尾零的个数为 y , 则 lowbit(x) == 2^y void Update(int i,int v)

  • redis数据结构之intset的实例详解

    redis数据结构之intset的实例详解 在redis中,intset主要用于保存整数值,由于其底层是使用数组来保存数据的,因而当对集合进行数据添加时需要对集合进行扩容和迁移操作,因而也只有在数据量不大时redis才使用该数据结构来保存整数集合.其具体的底层数据结构如下: typedef struct intset { // 编码方式 uint32_t encoding; // 集合包含的元素数量 uint32_t length; // 保存元素的数组 int8_t contents[]; }

  • 数据结构串的操作实例详解

    数据结构串的操作实例详解 串是一种特殊的线性表,它的每个结点是一个字符,所以串也称作字符串. 关于串的操作主要有求串长,串复制,串连接,求子串,串插入,串删除,子串定位等.串的操作也是C语言笔试中常考的一部分. 下面的代码实现了串的主要操作. #include <stdio.h> #include <stdlib.h> #define MAXSIZE 20 char *String_Create(); //创建串 int String_Length(char *s); //求串长

  • C语言数据结构之单链表操作详解

    目录 1.插入操作 2.删除操作 3.查找操作 4.修改操作 5.完整代码 1.插入操作 (1)创建一个新的要插入的结点 (2)将新结点的 next 指针指向插入位置后的结点 (3)将插入位置前的节点指针 next 指向新的结点 注意:步骤(2)(3)的顺序不能颠倒,否则会导致插入位置后的部分链表丢失. 插入位置一共分三种,分别是头部插入.中间插入和尾部插入. 如图: 代码: link* insertElem(link* p,int elem,int pos){ link* temp = p;/

  • Kotlin 语言中调用 JavaScript 方法实例详解

    Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J

  • 数据结构 栈的操作实例详解

    数据结构 栈的操作实例详解 说明: 往前学习数据结构,想运行一个完整的顺序栈的程序都运行不了,因为书上给的都是一部分一部分的算法,并没有提供一个完整可运行的程序,听了实验课,自己折腾了一下,总算可以写一个比较完整的顺序栈操作的小程序,对于栈也慢慢开始有了感觉.下面我会把整个程序拆开来做说明,只要把这些代码放在一个文件中,用编译器就可以直接编译运行了. 一.实现 1.程序功能 关于栈操作的经典程序,首当要提及进制数转换的问题,利用栈的操作,就可以十分快速地完成数的进制转换. 2.预定义.头文件导入

  • C语言中联合体union的实例详解

     C语言中联合体union的实例详解 1.定义: union(int i, short s, char c) un; un.i = 3; printf("i=%d",un.i); printf("length = %d\n",sizeof(un);//==4,有最大的变量来决定 2.相当与java里的List T类型 3.数据交换 void swap(int *p , int *q){ int temp = *p; *p = *q; *q = temp; } 4.打

随机推荐