【数据结构】 顺序表查找(折半查找&&差值查找)
#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 国际化
国际化英文单词为:Internationalization,又称I18N,I为因为单词的第一个字母,18为这个单词的长度,而N代表这个单词的最后一个字母.国际化又称本地化(Localization,L ...
- Oracle数据库之PL/SQL程序基础设计
一.PL/SQL块结构 前边我们已经介绍了PL/SQL块的结构,再来回顾一下: DECLARE /* * 声明部分——定义常量.变量.复杂数据类型.游标.用户自定义异常 */ BEGIN /* * 执 ...
- Day7:掌握APICloud应用管理相关服务的配置使用和相关API,包括:应用发布、版本管理、云修复、闪屏广告等。理解APICloud APP优化策略和编码规范;了解APICloud多Widget管理机制和SuperWebview的使用
主要内容: 1. 应用发布 1.1 云编译 1.2 全包加密 网页全包加密:对网页中全包的html,css,javascript代码进行加密,加密后的网友代码都是不可读的,并且不能通过常用的格式化工具 ...
- 从一个带有http://网络文件中获取文件名
例如文件网址为: http://a.hiphotos.baidu.com/image/h%3D200/sign=c3da85e50123dd543e73a068e108b3df/80cb39dbb6f ...
- SpringBoot+Mybatis+Generator 逆向工程使用(二)
Mybatis-Genarator 逆向工程使用 个人开发环境 java环境:Jdk1.8.0_60 编译器:IntelliJ IDEA 2017.1.4 mysql驱动:mysql-connecto ...
- poj 1849 Two 树形dp
Two Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 1092 Accepted: 527 Description Th ...
- 云服务器部署mongodb
我喜欢用简单的方法 步骤 下载 解压并运行 远程连接测试 下载 到官方下载页获取下载地址,如图 在云服务器上,使用命令curl 你的地址 -o mongodb.tgz ,下载到当前目录,转到下一步. ...
- Linux学习6-Linux常用命令(1)
1.命令格式:命令 [-选项] [参数] 例如:ls -la /etc 说明: 1)个别命令使用不遵循此格式 2)当有多个选项时,可以写在一起 3)简化选项与完整选项 (-a等于 -- ...
- sql or语法
1.mysql中or语法的使用,在mysql语法中or使用注意点. 项目遇到坑,遍历发放奖励数据查询错误!!! $sql = 'SELECT * FROM `vvt_spread_doubleegg_ ...
- JSONP 教程
JSONP 教程 本章节我们将向大家介绍 JSONP 的知识. Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获 ...