线性时间选择2
2015-10-10 22:22
267 查看
#include "stdio.h" void swap(int &a, int &b) { int temp = a; a = b; b = temp; } int part(int a[],int left, int right, int x) { //将小于x的元素移到左区间,将大于x的元素移到右区间 int i = left, j = right; while(true) { while(i<right && a[i++]<x); //左半区间x小,指针右移 while(j>left && a[j--]>x); //右半区间比x大,指针左移 if(i>=j) //左右指针相遇,跳出循环 { break; } swap(a[i],a[j]); //将大于x的元素交换到右区间,小于x的元素交换到左区间 } return j; } int partion(int a[], int left, int right) { //将小于数组a[]第一个元素的元素移到左区间,将大于a[0]的元素移到右区间 int i = left; int j = right; int temp = a[left]; while(i<j) { while(i<j && a[j]>temp) //如果右边元素大于参照元素 j--; //右面区间下标左移 a[i] = a[j]; //将右边小于参照元素的元素移到左区间 while(i<j && a[i]<temp) //如果左边元素小于参照元素 i++; //左面下标右移 a[j] = a[i]; //将左边大于参照元素的元素移到右区间 } a[i] = temp; //将参照元素放置到合适的位置 return i; //返回参照元素下标 } void quickSort(int a[], int left, int right) { if(left<right) //递归结束条件 { int mid = partion(a, left, right); quickSort(a, left, mid); //对左段区间递归排序 quickSort(a, mid+1, right); //对右段区间递归排序 } } int select(int a[], int left, int right, int k) //在a[left:right]中选择第k小的元素并返回 { if(right-left < 30) { quickSort(a, left, right); //用快速排序对a[]进行排序 return a[left+k-1]; //返回第k小元素 } else { int n = right - left + 1; //数组a[]中元素个数 int i, j; for(i=0; i<=(n-5)/5; i++) // n/5(向上取整)组数字 { //将元素每5个分成一组,分别排序,并将该组中位数与a[left+i]交换位置 //使所有中位数都排列在数组最左侧,以便进一步查找中位数的中位数 quickSort(a, left+5*i, left+5*i+4); swap(a[left+5*i+2], a[left+i]); } int x = select(a, left, left+(n-5)/5, (n-5)/10); //找中位数的中位数 int mid = part(a, left, right, x); //a[left:mid]中每个元素都小于x,a[mid+1:right]中的元素都大于x int count = mid - left + 1; //左半区间长度 if(k<=count) //如果第k小元素落在字数在a[left:mid]中 return select(a, left, mid, k); //在a[left:mid]中寻找第k小元素 else return select(a, mid+1, right, k-count); //在a[mid+1:right]中寻找第k-j元素 } } int main() { int a[100]; int len; int i, k; printf("输入元素个数:"); scanf("%d", &len); printf("输入元素:"); for(i=0; i<len; i++) scanf("%d", &a[i]); printf("想要查找第k小元素:k="); scanf("%d", &k); int f = select(a, 0, len-1, k); printf("%d\n", f); return 0; }
相关文章推荐
- 线性时间选择1
- 数据库原理之一(ER图)
- linux根目录下各文件夹的作用
- 棋盘覆盖
- Rational Rose
- poj 3667 Hotel(线段树)
- Django+Markdown+Pygments 支持Markdown 实现代码高亮
- Java基础知识强化之IO流笔记36:InputStreamReader/OutputStreamWriter 复制文本文件案例
- 排列问题
- poj 2104 K-th Number (主席树学习第一弹)
- 快速排序
- 第二阶段
- Windows - 程序猿应该熟记的CMD常用命令
- 对Xcode7真机调试的无力吐槽
- 归并排序
- View的事件分发机制。
- Java的序列化与反序列化
- 二分搜索
- 第114讲:Hadoop集群安装解析学习笔记
- resizableImageWithCapInsets实现登录按钮、胶囊tab按钮和聊天气泡贴图效果