#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXSIZE 10

首先构造一个数组, 由随机数生成, 同时确保没有重复元素。(为了排序之后查找时候方便)

为了确保没有重复的元素使用了一个简单的查找函数:

用数组的0号元素来作为哨兵

化简了操作:

int search0(int *a,int length,int key)
{
int i;
a[] = key;
i = length;
while(a[i]!=key)
{
i--;
}
return i; //这样如果没有查找到元素,就会return 0;
}
int a[MAXSIZE] = {};
int i;
int find;
int rec;
srand((unsigned)time(NULL));
for(i=;i<MAXSIZE+;i++)
{
a[i] = rand()%+;
while(search0(a,i-,a[i])!=&&i!=&&i!=MAXSIZE+)
a[i]=rand()%+;
}

还需要一个函数 显示数组里所有元素:

void print_List(int *a,int length)
{
int i;
printf("List:");
for(i=;i<length+;i++)
{
printf(" %d ",a[i]);
}
printf("\n");
}

使用冒泡法进行排序:

void sort(int *a,int length)
{
int i,j;
int t;
for(i=;i<length+;i++)
{
for(j=i+;j<length+;j++)
{
if(a[i]>a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
}

之后是折半查找的函数:

int search_half(int *a,int length,int key)
{
int low,high,mid;
low = ;
high = length;
int n = ;
while(low<=high)
{
//mid = (low + high)/2; //折半查找
mid = low+ (high - low)*(key-a[low])/(a[high]-a[low]); //差值查找
printf("%d: low = %d high = %d mid = %d\n",n,low,high,mid);
if(key<a[mid])
high= mid - ;
else if (key>a[mid])
low = mid + ;
else
return mid;
n++;
}
return ;
}

首先需要确保是一个有序的表,这样通过比较key 和 mid的大小

如果key小于mid则说明key可能在小于mid的区域 high 调整

如果key大于mid则说明key可能在大于mid的区域 low 调整

相等就找到了

效果如图:

那么另一个问题出现了:为什么一定要折半呢?

比如说在0~1000内查找5 折半就很不明智了吧。

最初的公式可以理解为:

  mid = (low+high)/2 = low+1/2*(high - low)

  即 在low这个基础数值上附加了一个数值 (这里是选择区间数值的一半), 如果我们想改进这个公式, 显然应该改进那个附加值 改为与key 相关

mid = low+(key-a[low])/(a[high]-a[low])*(highj - low)

比如说还是在 0~1000个内寻找5

第一次的mid 修改为 mid = 0+(5-0)/(1000-0)*1000 = 5   显然能看出 当插值明显很小(或者很大) mid 的取值取决于key在整体的大小趋势, 这样mid也会明显变小(或者很大)

测试, 将MAXSIZE 增大为20

比常规的折半相比, 速度更快了。

完整程序:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXSIZE 20
void print_List(int *a,int length)
{
int i;
printf("List:");
for(i=;i<length+;i++)
{
printf(" %d ",a[i]);
}
printf("\n");
} void sort(int *a,int length)
{
int i,j;
int t;
for(i=;i<length+;i++)
{
for(j=i+;j<length+;j++)
{
if(a[i]>a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
}
int search0(int *a,int length,int key)
{
int i;
a[] = key;
i = length;
while(a[i]!=key)
{
i--;
}
return i;
}
int search_half(int *a,int length,int key)
{
int low,high,mid;
low = ;
high = length;
int n = ;
while(low<=high)
{
//mid = (low + high)/2; //折半查找
mid = low+ (high - low)*(key-a[low])/(a[high]-a[low]); //差值查找
printf("%d: low = %d high = %d mid = %d\n",n,low,high,mid);
if(key<a[mid])
high= mid - ;
else if (key>a[mid])
low = mid + ;
else
return mid;
n++;
}
return ;
}
int main()
{
int a[MAXSIZE] = {};
int i;
int find;
int rec;
srand((unsigned)time(NULL));
for(i=;i<MAXSIZE+;i++)
{
a[i] = rand()%+;
while(search0(a,i-,a[i])!=&&i!=&&i!=MAXSIZE+)
a[i]=rand()%+;
}
print_List(a,MAXSIZE);
sort(a,MAXSIZE);
print_List(a,MAXSIZE);
while()
{
printf("你想查找的数据为:");
scanf("%d",&find);
rec=search_half(a,MAXSIZE,find);
if(rec != )
printf("编号为:%d\n",rec);
else
printf("没找到\n");
}
return ;
}

【数据结构】 顺序表查找(折半查找&&差值查找)的更多相关文章

  1. hrbustoj 1545:基础数据结构——顺序表(2)(数据结构,顺序表的实现及基本操作,入门题)

    基础数据结构——顺序表(2) Time Limit: 1000 MS    Memory Limit: 10240 K Total Submit: 355(143 users) Total Accep ...

  2. hrbust-1545-基础数据结构——顺序表(2)

    http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1545 基础数据结构——顺序表(2) ...

  3. 数据结构---顺序表(C++)

    顺序表 是用一段地址连续的存储单元依次存储线性表的数据元素. 通常用一维数组来实现 基本操作: 初始化 销毁 求长 按位查找 按值查找 插入元素 删除位置i的元素 判空操作 遍历操作 示例代码: // ...

  4. 数据结构——顺序表(sequence list)

    /* sequenceList.c */ /* 顺序表 */ /* 线性表的顺序存储是指在内存中用地址连续的一块存储空间顺序存放线性表中的各项数据元素,用这种存储形式的线性表称为顺序表. */ #in ...

  5. 数据结构 - 顺序表 C++ 实现

    顺序表 此处实现的顺序表为**第一个位置为 data[0] **的顺序表 顺序表的定义为 const int MAX = 50; typedef int ElemType; typedef struc ...

  6. python算法与数据结构-顺序表(37)

    1.顺序表介绍 顺序表是最简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以快速定位第几个元素,中间不允许有空,所以插入.删除时需要移动大量元素.顺序表可以分配一段连续的存储空间 ...

  7. 数据结构顺序表中Sqlist *L,&L,Sqlist *&L

    //定义顺序表L的结构体 typedef struct { Elemtype data[MaxSize]: int length; }SqList; //建立顺序表 void CreateList(S ...

  8. c数据结构 顺序表和链表 相关操作

    编译器:vs2013 内容: #include "stdafx.h"#include<stdio.h>#include<malloc.h>#include& ...

  9. 数据结构顺序表删除所有特定元素x

    顺序表类定义: template<class T> class SeqList : { public: SeqList(int mSize); ~SeqList() { delete[] ...

随机推荐

  1. activemq的三种通信方式

    一.安装与启动 1.下载安装activemq,下载地址:http://activemq.apache.org/download.html. 2.安装完成后,进入其所在目录的bin目录下面,根据系统位数 ...

  2. Rails 建立一个资源

    在blog 应用程序中.你可以通过脚手架(scaffolded)开始建立一个资源. 这将是单一的blog 提交.请输入以下命令 $ rails generate scaffold Post name: ...

  3. golang基础--map字典

    map 类似python语言中的dict(字典类型),以key-value形式存储数据 Key必须是支持==或!=比较运算的类型,不可以是函数,map或slice map查找比线性搜素快很多,但比使用 ...

  4. [PY3]——threading.Event

    Class Event { __init__(self) clear(self) is_set(self) set(self) wait(self,timeout=None) } is_set(sel ...

  5. CUBA 7 新特性 (下篇)

    上篇我们主要介绍了 CUBA 7 中前端的一些主要功能.这篇我们介绍一下中间件的一变化和新特性. 中间件功能 前面关于新的界面 API 的描述内容比我预期的要多许多,所以在这一节,我会尽量简单点说! ...

  6. [转] Linux Daemon Writing HOWTO

    Linux Daemon Writing HOWTO Devin Watson v1.0, May 2004 This document shows how to write a daemon in ...

  7. SQL Server数据库状态和文件状态

    数据库状态 (database states) 查询数据库的当前状态 : 1.查询所有数据库的状态 ,通过sys.databases目录视图的state_desc列 user master go se ...

  8. MFC动态时间表示法——strtime函数

    %a 星期几的简写 %A 星期几的全称 %b 月分的简写 %B 月份的全称 %c 标准的日期的时间串 %C 年份的后两位数字 %d 十进制表示的每月的第几天 %D 月/天/年 %e 在两字符域中,十进 ...

  9. MyEclipse中更改JRE环境

    今天代码中需要用到λ表达式,但λ表达式需要JRE1.8的支持,而MyEclipse设置的默认JRE是1.7.为了是程序能够顺利通过编译,需要将MyEclipse的JRE由1.7转换为1.8.步骤如下:

  10. PHP 抽象类实现接口注意事项(含PHP与.Net的区别)

    最近在学习Drupal8,看到源码里面一个抽象类BlockBase实现了一个接口BlockPluginInterface,但是并没有实现该接口的所有方法.然后我就不淡定了,因为之前是做.NET的,记忆 ...