有序(循环)数组查找元素-二分查找法
来源:互联网 发布:python基础教程 mobi 编辑:程序博客网 时间:2024/04/25 23:36
1.我们将一个有序数组(n个元素)从i(号位置)之前放到n位置之后形成的数组为有序循环数组。
2.数组 1 2 4 5 6 7 8
的有序循环数组有
1 2 4 5 6 7 8 (元数组是位置0处的有序循环数组).
2 4 5 6 7 8 1
4 5 6 7 8 1 2
5 6 7 8 1 2 4
6 7 8 1 2 4 5
7 8 1 2 4 5 6
8 1 2 4 5 6 7
3.我们要在有序循环数组中找到一个元素出现的位置(此处假设每个元素出现次数小于等于一)。
a.顺序差 O(n)
b.(二次)二分查找O(2logn) ~ O(logn)。
此处先说明一下二分查找.
若数组有序那么我们取首个位置为l,最后位置为r,中间位置为m=(l+r) /2,要找的元素为val
l<=r时
若A [ m] ==val则找到.
若A[m]>val 则在左边找l=m-1;
若A[m]<val则在右边找r=m+1;
重复过程直到找到.
有下列.
在0 2 3 4 7 8 10 11 70 100 101 中查找 7 ,则会在第三步找到.
若查找5则会在第四步找不到退出。
给出代码:
#include <stdio.h>#define SIZE 100int binary_find(int number[],int l,int r,int val){ int lft = l, rit = r ,mid = lft; while( lft <= rit ){ mid = (rit + lft)/2; if( number[mid] == val){ return mid; }else if(number[mid] > val){ rit = mid - 1; }else{ lft = mid + 1; } } return -1;}int main(){ int number[SIZE] = {5,8,10,11}; int i,count=4,val=11,mid=-1; mid = binary_find(number,0,count-1,,val); if(mid!=-1){ printf("find :%d at pos:%d!\n",number[mid],mid); }else{ printf("nomber %d !\n",val); } getchar(); return 0;}
现在来考虑问题在循环有序中的数组中查找元素出现的位置。
假设你知道那个边界点位置为i(i和前面元素有序并且大于每一个i后面的有序序列中的元素元素。
10 11 70 100 101 0 2 3 4 7 8 此处的边界点i为4(从零计算下标)
那么可以将0-4挪到11~15位置,在使用二分查找从(5,15)查找即可。
那么就有新的问题如何找到原序列中的边界点。
1.若果原序列有序,或者只有一个元素直接二分查找。
2.否则为循环多元素的数组,那么需要找分界点.
分界点的特点就在于.
i是分界点下表 a[i] > a[i+1]
若a[pos] < a[r] 则分界点在pos左边(r右边界下标)
若a[pos] > a[l] 则分界点在pos右边(l左边界下标)
相当于换了一次二分查找的条件来查找分界点位置.
找到之后就是来映射分界点左边的元素到分界点右边元素之后。如图
若当前位置为pos,原来右下标为r-1 pos >= r 是真实位置是pos - (r - l - pos);
否则就是本身。
给出代码:
#include <stdio.h>#define SIZE 100int main(){ int number[SIZE] = {5,6,7,8}; int i,count=4,val=6; int lft = 0, rit = count - 1 ,mid = lft,pos = -1,key_pos; for(i=0;i < count;i++){ printf("%d ",number[i]); } if( number[0] <= number[count - 1] ){ //原本为有序串,直接二分查找 while( lft <= rit ){ mid = (rit + lft)/2; if( number[mid] == val){ printf("find :%d at pos:%d\n",number[mid],mid); break; }else if(number[mid] > val){ rit = mid - 1; }else{ lft = mid + 1; } } if(lft>rit) printf("no meber :%d\n",val); }else{ //查找分界点 while( lft <= rit ){ mid = (rit + lft)/2; if( number[mid] >= number[mid + 1] ){ break; }else if(number[mid] <= number[count - 1 ]){ rit = mid - 1; }else{ lft = mid + 1; } } lft = mid + 1,rit = count + mid ,key_pos = mid; while( lft <= rit ){ //进行查找元素 mid = (rit + lft)/2; int pos = mid >= count ? mid -(count - key_pos + 1) : mid; if( number[pos] == val){ printf("find :%d at pos:%d\n",number[pos],pos); break; }else if(number[pos] > val){ rit = mid - 1; }else{ lft = mid + 1; } } if(lft>rit) printf("no meber :%d\n",val); } return 0;}
- 有序(循环)数组查找元素-二分查找法
- 有序 循环数组的二分查找
- 查找循环有序数组的元素
- 有序数组\二分查找
- 有序数组二分查找
- 二分数组的扩展:二分查找循环有序数组
- 循环有序数组查找
- 基本查找:数组元素无序(从头找到尾) * 二分查找(折半查找):数组元素有序
- 循环有序数组/旋转数组的二分查找
- Java数组-二分查找法用于元素插入有序数组,并获取元素插入的位置
- 二分查找进阶——循环有序数组查找再进阶——循环有序重复数组查找
- 插入元素到有序数组,二分搜索查找插入位置
- 带有重复元素的有序数组二分查找
- 有序数组中的二分查找
- 有序数组的二分查找
- 有序数组之二分查找
- 有序数组的二分查找
- 有序数组的二分查找
- 【数据结构】——排序算法——1.2、希尔shell排序
- 定义一个结构体变量,计算该日在该年中是哪一天
- 计数排序及并行实现
- tomcat启动错误 之 端口被占用
- Eclipse开发Android程序如何在手机上运行
- 有序(循环)数组查找元素-二分查找法
- android笔记2『个人笔记!非教程!慎入!』
- C++构造函数调用顺序
- Trie树 poj2503
- 重构之心得体会
- Merge Two Sorted Lists
- new与malloc的区别和联系
- 适合自己的才是最好的
- 求一个整数各位数的和