【数据结构】 顺序表查找(折半查找&&差值查找)
#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 ;
}
【数据结构】 顺序表查找(折半查找&&差值查找)的更多相关文章
- hrbustoj 1545:基础数据结构——顺序表(2)(数据结构,顺序表的实现及基本操作,入门题)
基础数据结构——顺序表(2) Time Limit: 1000 MS Memory Limit: 10240 K Total Submit: 355(143 users) Total Accep ...
- hrbust-1545-基础数据结构——顺序表(2)
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1545 基础数据结构——顺序表(2) ...
- 数据结构---顺序表(C++)
顺序表 是用一段地址连续的存储单元依次存储线性表的数据元素. 通常用一维数组来实现 基本操作: 初始化 销毁 求长 按位查找 按值查找 插入元素 删除位置i的元素 判空操作 遍历操作 示例代码: // ...
- 数据结构——顺序表(sequence list)
/* sequenceList.c */ /* 顺序表 */ /* 线性表的顺序存储是指在内存中用地址连续的一块存储空间顺序存放线性表中的各项数据元素,用这种存储形式的线性表称为顺序表. */ #in ...
- 数据结构 - 顺序表 C++ 实现
顺序表 此处实现的顺序表为**第一个位置为 data[0] **的顺序表 顺序表的定义为 const int MAX = 50; typedef int ElemType; typedef struc ...
- python算法与数据结构-顺序表(37)
1.顺序表介绍 顺序表是最简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以快速定位第几个元素,中间不允许有空,所以插入.删除时需要移动大量元素.顺序表可以分配一段连续的存储空间 ...
- 数据结构顺序表中Sqlist *L,&L,Sqlist *&L
//定义顺序表L的结构体 typedef struct { Elemtype data[MaxSize]: int length; }SqList; //建立顺序表 void CreateList(S ...
- c数据结构 顺序表和链表 相关操作
编译器:vs2013 内容: #include "stdafx.h"#include<stdio.h>#include<malloc.h>#include& ...
- 数据结构顺序表删除所有特定元素x
顺序表类定义: template<class T> class SeqList : { public: SeqList(int mSize); ~SeqList() { delete[] ...
随机推荐
- Java 集合框架(二)—— ArrayList
二.数组列表 —— ArrayList 1.构造方法 ArrayList 是 Java 中的动态数组,底层实现就是对象数组,只不过数组的容量会根据情况来改变. 它有个带 int 类型参数的构造方法,根 ...
- DC综合及仿真验证和DFT测试
综合技术是提高设计产能的一个很重要的技术,没有综合技术的发展就不可能用HDL实现电路的设计,因为HDL开始是用来供电路仿真建模使用的,到了后来才把其中一部分子集作为可综合的语言,也就是R ...
- Oracle 12c 建表空间语句
create tablespace TBS_DYS datafile 'D:/Oracle_12c/app/dingyingsi/oradata/dingyingsi/TBS_DYS.ba' size ...
- SharePoint 2013 EventHanlder工具
之前在07的时候使用SharePoint Event Receiver Manager (2007 & 2010)来管理SharePoint的Event Handler,但是2013后作者没有 ...
- BATJ面试必会之 Spring 篇(一)
译者:深海 校对:方腾飞 出自并发编程网 – ifeve.com 目录 Spring 概述 依赖注入 Spring beans Spring注解 Spring数据访问 Spring面向切面编程(AOP ...
- XP系统运行wpf程序出现透明现象的解决
xp 虚拟机运行WPF程序的时候,有部分控件透明,在这儿有一个可能的解决方案: 关闭系统的硬件加速: 1. 按“WIN” + R 键,在“运行”输入框中输入“dxdiag”: 2. 在“DirectX ...
- 双11抢券,写一个自动打开页面的html,仅仅是设定时间打开抢券的页面
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- [日常] nginx与HTTP cache
去年的事,随便记记 =============================================================2017年12月11日 记录: nginx缓存:ngx_h ...
- [转]linux文件批量转码
linux系统里提供的文件转化编码的命令iconv,例如: iconv -t utf- -f gb2312 -c test.xml > text_UTF8.xml -f 源编码-t 目标编码 ...
- 使用tcmalloc替换系统的malloc
https://blog.csdn.net/educast/article/details/79166553?utm_source=blogxgwz0 今天对服务器进行压测,模拟的请求量到4万次/分的 ...