C语言编程中实现二分查找的简单入门实例_C 语言

架设有一个数组 v 已经按升序排列了,数组 v 有 n=20 个元素。数组中有个元素 x,如何知道 x 位于该数组的第几位呢?
解决这个问题的一个普遍方法就是二分查找法。下面是程序:

#include <stdio.h>
int binsearch(int x, int v[], int n);
main()
{
  int i, result, n;
 int wait;

  int x = 17; // 需要查找的数值
 int v[19]; // 定义一个数组
 // 给数组赋值
 for(i = 0; i < 20; ++i)
   v[i] = i;
 /**
 for(i = 0; i < 20; ++i)
 printf("%d \n", v[i]);
 */
 n = 20;
 result = binsearch(x, v, n);
 printf("%d", result);
 scanf("%d", &wait);
}
int binsearch(int x, int v[], int n)
{
 int low, high, mid;
 low = 0;
 high = n - 1;
 while (low <= high)
 {
 mid = (low + high) / 2;
 if(x < v[mid])
  high = mid - 1;
 else if (x > v[mid])
  low = mid + 1;
 else
  return mid;
 // 看看循环执行了多少次
 printf("mid = %d, low = %d, high = %d \n", mid, low, high);
 }
 return -1;
}

1、二分查找法

    二分查找法有一个很重要的前提条件:即待查找的序列必须是已经排好序的。

    假设元素序列是按升序排列,将序列中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将序列分成前、后两个子序列,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子序列,否则进一步查找后一子序列。重复以上过程,直到找到满足条件的记录,查找成功,返回元素在序列中的索引,或直到子序列不存在为止,此时查找失败,返回-1。

 

int find2(int *array,int n,int val)
{
  if (n<=0)
  {
    return -1;
  } 

  int begin=0,end=n-1,mid;
  while(begin<=end)
  {
    mid=(begin+end)/2;
    if (array[mid]==val)
      return mid;
    else if(array[mid]>val)
      end=mid-1;
    else
      begin=mid+1;
  } 

  return -1;
}

2、使用二分查找树查找

    首先创建一颗二分查找树,我们知道二分查找树的特点是左子树的值都比根节点小,右子树的值都比根节点大,且二分查找树的中序遍历所得到的元素是排好序的。

//二叉查找树数据结构
typedef struct Btree
{
  int data;
  Btree *left;
  Btree *right;
}*PBTree; 

//创建二叉查找树,返回树的根节点
PBTree CreateBTree(int *array,int n)
{
  PBTree root=new Btree;
  root->data=array[0];
  root->left=NULL;
  root->right=NULL; 

  PBTree current,back,pNew;
  for (int i=1;i<n;i++)
  {
    pNew=new Btree;
    pNew->data=array[i];
    pNew->left=pNew->right=NULL;
    current=root;
    while(current!=NULL)  //找到合适的插入位置
    {
      back=current;
      if(current->data>array[i])
        current=current->left;
      else
        current=current->right;
    }
    if(back->data>array[i])
      back->left=pNew;
    else
      back->right=pNew;
  } 

  return root;
} 

//利用二叉查找树进行递归查找
bool find3(PBTree root,int val)
{
  if (root==NULL)
    return false;
  if (root->data==val)
    return true;
  else if(root->data>val)
    return find3(root->left,val);
  else
    return find3(root->right,val);
}

3、总结

    二分查找有非常严格的限制条件(序列必须是有序的);

    而使用二分查找树,则会自动创建出"有序树"(中序遍历得到的序列是有序的);

    不考虑二叉查找树的建立时间,二者的效率一样,均为O(logn)。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c语言
, 二分查找
, 入门
C语言入门
c语言编程入门实例、c语言编程实例、c语言100经典实例编程、c语言编程学习入门、c语言编程入门教程,以便于您获取更多的相关知识。

时间: 2024-11-27 12:32:02

C语言编程中实现二分查找的简单入门实例_C 语言的相关文章

在C语言编程中设置和获取代码组数的方法_C 语言

C语言setgroups()函数:设置组代码函数头文件: #include <grp.h> 定义函数: int setgroups(size_t size, const gid_t * list); 函数说明:setgroups()用来将list 数组中所标明的组加入到目前进程的组设置中. 参数size 为list()的gid_t 数目, 最大值为NGROUP(32). 返回值:设置成功则返回0, 如有错误则返回-1. 错误代码: EFAULT:参数list 数组地址不合法. EPERM:权限

C语言二分查找算法及实现代码_C 语言

二分査找也称折半査找,其优点是查找速度快,缺点是要求所要査找的数据必须是有序序列.该算法的基本思想是将所要査找的序列的中间位置的数据与所要査找的元素进行比较,如果相等,则表示査找成功,否则将以该位置为基准将所要査找的序列分为左右两部分.接下来根据所要査找序列的升降序规律及中间元素与所查找元素的大小关系,来选择所要査找元素可能存在的那部分序列,对其采用同样的方法进行査找,直至能够确定所要查找的元素是否存在,具体的使用方法可通过下面的代码具体了解. #include <stdio.h> binar

对C语言中指针的理解与其基础使用实例_C 语言

C语言的指针,关键意思在于"指". "指"是什么意思? 其实完全可以理解为指示的意思.比如,有一个物体,我们称之为A.正是这个物体,有了这么个称谓,我们才能够进行脱离这个物体的实体而进行一系列的交流.将一个物体的指示,是对这个物体的抽象.有了这种抽象能力,才有所谓的智慧和文明.所以这就是"指示"这种抽象方法的威力. 退化到C语言的指针,指针是一段数据/指令(在冯诺易曼体系中,二者是相通,在同一空间中的)的指示.这是指示,也就是这段数据/指令的起始

C++编程中指针的声明与基本使用讲解_C 语言

使用以下序列声明指针. [storage-class-specifiers] [cv-qualifiers] type-specifiers [ms-modifier] declarator ; 其中,任何有效指针声明符均可用于 declarator.简单指针声明符的语法如下所示: * [cv-qualifiers] identifier [= expression] 1.声明说明符: 可选存储类说明符. 应用于要指向的对象的类型的可选 const 或 volatile 关键字. 类型说明符:可

实例讲解C++编程中的虚函数与虚基类_C 语言

虚函数① #include "stdafx.h" #include <iostream> using namespace std; class B0//基类B0声明 { public: void display(){cout<<"B0::display()"<<endl;}//公有成员函数 }; class B1: public B0//公有派生类B1声明 { public: void display(){cout<<

深入解析C++编程中范围解析运算符的作用及使用_C 语言

范围解析运算符 :: 用于标识和消除在不同范围内使用的标识符. 语法 复制代码 代码如下: :: identifier class-name :: identifier namespace :: identifier enum class :: identifier enum struct :: identifier 备注identifier 可以是变量.函数或枚举值.具有命名空间和类以下示例显示范围解析运算符如何与命名空间和类一起使用: namespace NamespaceA{ int x;

讲解C语言编程中指针赋值的入门实例_C 语言

从const int i 说起 你知道我们声明一个变量时象这样int i :这个i是可能在它处重新变赋值的.如下: int i = 0; /* . . . */ i = 20; /*这里重新赋值了*/ 不过有一天我的程序可能需要这样一个变量(暂且称它变量),在声明时就赋一个初始值.之后我的程序在其它任何处都不会再去重新对它赋值.那我又应该怎么办呢?用const . /* . . . */ const int ic =20; /* . . . */ ic = 40; /*这样是不可以的,编译时是无

详解C++编程中向函数传递引用参数的用法_C 语言

引用类型的函数参数向函数传递引用而非大型对象的效率通常更高. 这使编译器能够在保持已用于访问对象的语法的同时传递对象的地址. 请考虑以下使用了 Date 结构的示例: // reference_type_function_arguments.cpp struct Date { short DayOfWeek; short Month; short Day; short Year; }; // Create a Julian date of the form DDDYYYY // from a G

举例讲解C语言程序中对二叉树数据结构的各种遍历方式_C 语言

二叉树遍历的基本思想 二叉树的遍历本质上其实就是入栈出栈的问题,递归算法简单且容易理解,但是效率始终是个问题.非递归算法可以清楚的知道每步实现的细节,但是乍一看不想递归算法那么好理解,各有各的好处吧.接下来根据下图讲讲树的遍历. 1.先序遍历:先序遍历是先输出根节点,再输出左子树,最后输出右子树.上图的先序遍历结果就是:ABCDEF  2.中序遍历:中序遍历是先输出左子树,再输出根节点,最后输出右子树.上图的中序遍历结果就是:CBDAEF 3.后序遍历:后序遍历是先输出左子树,再输出右子树,最后