数据结构------------查找(基于数据排序)

-----------------------文章参考《大话数据结构》--------------------------

1.基本概念

查找表:是由同一类型的元素构成的集合

关键字:数据元素中某个数据项的值

静态查找表和动态查找表

静态查找表:查询某个“特定的”数据元素是否在查找表中

查询某个“特定的”数据元素和各种属性

动态查找表:在查找的过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素

2.各种查找算法的比较

(1)线性查找

从表中的第一个(或最后一个)记录开始。组个进行记录的关键字和给定比值的比较,若某个记录的关键字和给定值相等,则查找成功。

C语言代码

 1 int Sequential_Serach(int a[],int n,int key){   //a为数组,n为要查找的数组长度,key为要查找的关键字
 2   int i;
 3   for(i=1;i<=n;i++){
 4
 5 if(a[i]=key)
 6   return i;
 7 }
 8 return 0;
 9 }

Java代码

1 public static int Sequuential_Search(int [] a,int key){
2     for(int i=1;i<=a.length;i++){
3           if(a[i]==key){
4                  return i;
5             }
6     }
7     return 0;
8 }
1 //线性查找表的优化
2 public int Sequential_Search2(int [] a,int key){
3    int i=a.length;
4    a[0]=key;    //设置a[0]为关键字值
5    while(a[i]!=key){    //从数组尾部开始查找
6       i--;
7       }
8      return i;   //返回0这说明查找失败,a[1]-a[n]中没有关键字
9 }

(2)折半查找

这种查找方法的前提是线性表中的记录必须是有顺序的,也就是说线性表必须采用顺序存储,基本思想:去取中间记录作为比较对象,若给定的值与中间记录的关键字相等,这还则查找成功,若给定值小于中间记录的关键字,则在左半区继续查找,相反在右半区进行查找,不断重复,找到为止。

C语言代码

 1 int Binary_Serach(int a [],int n,int key){
 2      int low,hing,mid;
 3      low=1;
 4      high=n;
 5      while(low<=high){
 6        mid=(low+high)/2;
 7        if(key<a[mid])
 8              high=mid-1;
 9        else if(key>a[mid])
10              low=mid-1;
11        else
12             return mid;
13       }
14       return 0;
15 }

Java代码

 1 public int Binary_Search(int [] a,int n,int key){
 2      int low,high,mid;
 3      low=1;
 4      high=n;
 5      while(low<=high){
 6        mid=(low+high)/2;
 7        if(key<a[mid])
 8            high=mid-1;
 9        else if(key>a[mid])
10            low=mid-1;
11        else
12            return mid;
13       }
14      return 0;
15 }

(3)插值查找

直接上代码吧

//在二分查找的基础上将mid=(low+high)/2换成了如下的
//mid=low+(high-low)*(key-a[low])/(a[high]-a[low])
 1 public int Binary_Search(int [] a,int n,int key){
 2      int low,high,mid;
 3      low=1;
 4      high=n;
 5      while(low<=high){
 6        mid=low+(high-low)*(key-a[low])/(a[high]-a[low]);
 7        if(key<a[mid])
 8            high=mid-1;
 9        else if(key>a[mid])
10            low=mid-1;
11        else
12            return mid;
13       }
14      return 0;
15 }

(4) 斐波拉契查找

先说一下什么是黄金分割吧

黄金分割是指将整体一分为二,较大部分与整体部分的比值等于较小部分与较大部分的比值,其比值约为0.618。这个比例被公认为是最能引起美感的比例,因此被称为黄金分割。

假设一个斐波拉契数列为1,1,2,3,5,8,13,21,34,55,89,········

随着数字的增加,斐波拉契数列的钱一个数和后一个数的比值越来越接近于0.618,我们正是利用了这个性质来进行查找,一个简单的示意图如下所示

mid的开始位置如何确定?

我们刚开始分割时要满足黄金比例分割,假设待查找数组的个数为n,我们在斐波拉契数列中找到满足F[k]大于n,且最接近于n,得到F[k]之后将前两个值作为划分的依据即F[k-1]和F[k-2]两部分。

大部分说明都忽略了一个条件的说明:n=F(k)-1, 表中记录的个数为某个斐波那契数小1这是为什么呢?

是为了格式上的统一,以方便递归或者循环程序的编写。表中的数据是F(k)-1个,使用mid值进行分割又用掉一个,那么剩下F(k)-2个。正好分给两个子序列,每个子序列的个数分别是F(k-1)-1与F(k-2)-1个,格式上与之前是统一的。不然的话,每个子序列的元素个数有可能是F(k-1),F(k-1)-1,F(k-2),F(k-2)-1个,写程序会非常麻烦。

查找的时候可以分为三种情况

(1)相等的时候,mid位置即为要查找的位置

(2)当要查找的key小于mid位置的值时,即在图示的左边,就更新high值,high=mid-1,k-=1;说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归的应用斐波那契查找

(3)当要查找的key大于mid位置的值时,即在图示的右边,就更新low的值,,low=mid+1,k-=2;说明:low=mid+1说明待查找的元素在[mid+1,hign]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找

C语言代码如下

 1 //斐波拉契查找
 2 int Fibonacci_Search(int a[],int n,int key){
 3     int low,high,mid,i,k;
 4     low=1;
 5     high=n;
 6     k=0;
 7     while(n>F[k]-1){   //计算n位于斐波拉契数列的位置
 8         k++;
 9     }
10     for(i=n;i<F[k]-1;i++){  //将不满的数值补全
11         a[i]=a[n];
12     }
13     while(low<=high){
14         mid=low+F[k]-1;  //计算当前分割的下标
15         if(key<a[mid]){
16             high=mid-1;
17             k=k-1;
18         }
19         else if(key>a[mid]){
20             low=mid+1;
21             k=k-2;
22         }
23         else{
24             if(mid<=n)
25                 return mid;   //若相等说明mid即为查找到的值
26             else
27                 return n;     //若大于n说明是补全的数值,返回n
28         }
29
30     }
31     return 0;   //没找到
32 }
时间: 2024-10-29 03:37:31

数据结构------------查找(基于数据排序)的相关文章

百万数据排序:优化的选择排序(堆排序)

  前一篇给大家介绍了<必知必会的冒泡排序和快速排序(面试必知)>,现在继续介绍排序算法          本博文介绍首先介绍直接选择排序,然后针对直接选择排序的缺点改进的"堆排序",堆排序非常适合:数组规模非常大(数百万或更多) + 严格要求辅助空间的场景.   直接选择排序 (一)概念及实现 直接选择排序的原理:将整个数组视为虚拟的有序区和无序区,重复的遍历数组,每次遍历从无序区中选出一个最小(或最大)的元素,放在有序区的最后,每一次遍历排序过程都是有序区元素个数增加,

12. 蛤蟆的数据结构进阶十二排序实现之直接插入法

12. 蛤蟆的数据结构进阶十二排序实现之直接插入法 本篇名言:"路是脚踏出来的 ,历史是人写出来的,人的每一步行动都在书定自己的历史. --吉鸿昌" 接下来看下直接插入法的实现. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47687631 1.  直接插入法 直接插入排序(straightinsertion sort) 每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序. 第一趟比较前两

python 数据结构与算法之排序(冒泡,选择,插入)

目录 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 数据结构与算法: 算法: 数据结构 冒泡排序法 选择排序法 插入排序法 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 计算机重要的几门课: 1.数据结构和算法 2.网络 3.操作系统 4.计算组成原理 数据结构与算法: 算法: 衡量算法的标准: 时间复杂度:就是程序代码执行的大概次数 小结: 时间复杂度是用来估计算法运行时间的一个式子(单位) 一般来说,时间复杂度高的算法比复杂度低的算法慢 常见的

一步一步写数据结构(BST-二叉排序树)

二叉排序树的重要性不用多说,下面用c++实现二叉排序树的建立,插入,查找,修改,和删除.难点在于删除,其他几个相对比较简单. 以下是代码: 1 #include<iostream> 2 using namespace std; 3 //定义节点 4 typedef struct BiNode 5 { 6 int data; 7 struct BiNode *lchild,*rchild; 8 }BiNode,*BiTree; 9 10 //插入函数 11 void insertBST(BiTr

16. 蛤蟆的数据结构进阶十六排序实现之基数排序

16. 蛤蟆的数据结构进阶十六排序实现之基数排序 本篇名言:"社会犹如一条船 ,每人都要有掌舵的准备.--易卜生" 我们来看下基数排序. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47760601 1.  基数排序 基数排序(radix sort)属于"分配式排序"(distributionsort),又称"桶子法"(bucket sort)或bin sort,顾名思义,

javascript数据结构与算法--高级排序算法

高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法---- 希尔排序和快速排序. 一:希尔排序: 希尔排序的核心理念是:首先比较距离较远的元素,而非相邻的元素. 基本原理:通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔. 下面我们来看看数组[0,9,1,8,7,6,2,3,5,4] 来使用希尔排序的原理:如下图: 代码分析如下: 1. 执行 "间隔序列=3的步骤" A.

18. 蛤蟆的数据结构进阶十八排序实现之快速排序

18. 蛤蟆的数据结构进阶十八排序实现之快速排序 本篇名言:"一个人做点好事并不难,难的是一辈子做好事,不做坏事.--毛泽东" 我们最后来看下快速排序,以及各个排序之间的一些信息汇总. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47817933 1.  快速排序 快速排序由C. A. R.Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分

21、任务十九——可视化数据排序

0.题目 基于任务18 限制输入的数字在10-100 队列元素数量最多限制为60个,当超过60个时,添加元素时alert出提示 队列展现方式变化如图,直接用高度表示数字大小 实现一个简单的排序功能,如冒泡排序(不限制具体算法),用可视化的方法表达出来 1.解答过程 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>task19</title> &

namenode示例 数据排序

2.0 数据排序 "数据排序"是许多实际任务执行时要完成的第一项工作,比如学生成绩评比.数据建立索引等.这个实例和数据去重类似,都是先对原始数据进行初步处理,为进一步的数据操作打好基础. 2.1 实例描述 对输入文件中数据进行排序.输入文件中的每行内容均为一个数字,即一个数据.要求在输出中每行有两个间隔的数字,其中,第一个代表原始数据在原始数据集中的位次,第二个代表原始数据. a.txt 7 4 3 b.txt 4 2 样例输出: 1 2 2 3 3 4 4 7 2.2 设计思路 这个