快速排序思想的应用--求数组中第k小的数
2012-07-14 10:37
232 查看
[b]1问题定义[/b]
[b] [/b]加入数组arr中数据是:4,0,1,0,2,3,那么第三小的元素是1,问怎么样快速的求出这个第k小的数。
[b]2.解决方案[/b]
[b]解法一:[/b]
利用STL中快速排序把数组进行排序,然后数组下标是k-1的就是我们要求的第k小的元素了,这种情况的时间复杂度接近于O(n*logn)。但是回头想一想这个算法是把数组进行了全排序,而我们只是要找到数组中第k小的数,这显然是“杀猪用了牛刀”。当然了时间复杂度较高也是正常的。
解法二:
想一想快速排序的思想:将数组中某一个元素m作为划分依据(我们假设为第一个元素,即m = arr[0]),遍历一遍数组,使得数组的格局变成这样的三个部分:(1)m前面的元素 (2)m (3)m后面的元素。其中m前面的元素小于m,m后面的元素大于m,这样找第k小的数正好可以借鉴这个思想,即:
1、若m前面的元素个数大于k,则第k小的数一定在m前面的元素中,这时我们只需要继续在m前面的元素中搜索第k小的数;
2、若m前面的元素个数小于k,则第k小的数一定在m后面的元素中,这是我们只需要继续在m后面的元素中搜索第k-s小的数,其中s是m前面的元素个数。
下面给出代码:(在vc6.0下测试)
这个代码多用了较多的辅助空间,为的是不改变原来的数组的元素的顺序。不知道这个代码有什么漏洞没有,大家帮帮找找。谢谢喽……
学习中的一点总结,欢迎拍砖哦^^
[b] [/b]加入数组arr中数据是:4,0,1,0,2,3,那么第三小的元素是1,问怎么样快速的求出这个第k小的数。
[b]2.解决方案[/b]
[b]解法一:[/b]
利用STL中快速排序把数组进行排序,然后数组下标是k-1的就是我们要求的第k小的元素了,这种情况的时间复杂度接近于O(n*logn)。但是回头想一想这个算法是把数组进行了全排序,而我们只是要找到数组中第k小的数,这显然是“杀猪用了牛刀”。当然了时间复杂度较高也是正常的。
解法二:
想一想快速排序的思想:将数组中某一个元素m作为划分依据(我们假设为第一个元素,即m = arr[0]),遍历一遍数组,使得数组的格局变成这样的三个部分:(1)m前面的元素 (2)m (3)m后面的元素。其中m前面的元素小于m,m后面的元素大于m,这样找第k小的数正好可以借鉴这个思想,即:
1、若m前面的元素个数大于k,则第k小的数一定在m前面的元素中,这时我们只需要继续在m前面的元素中搜索第k小的数;
2、若m前面的元素个数小于k,则第k小的数一定在m后面的元素中,这是我们只需要继续在m后面的元素中搜索第k-s小的数,其中s是m前面的元素个数。
下面给出代码:(在vc6.0下测试)
#include <iostream.h> #define MAX_SIZE 100 int Biger[MAX_SIZE]; int Smaller[MAX_SIZE]; int Select_kth_Small(int arr[],int n,int k) { if(n == 1) return arr[0]; int b = 0,s = 0,t = arr[0],temp_n,temp_k; int temp[MAX_SIZE]; for(int i = 1 ; i < n ; i++)//遍历集合 { if(arr[i] > t) Biger[b++] = arr[i]; //如果当前元素比t大,就将当前元素加入Biger[] else Smaller[s++] = arr[i];//反之就加入到Smaller,这里没有考虑set[0] } if(b == 0) { Biger[b++] = t;//if...else主要是为了防止t大于或小于其他所有元素的情况 } else { Smaller[s++] = t; } //如果Smaller集合中的元素个数大于K,说明第K小的元素必在其中 //否则一定在Biger中,且应该是Biger集合中第k-r小的元素 //更新相应的变量 if(s >= k) { temp_n = s; temp_k = k; for(i=0;i<temp_n;i++) { temp[i] = Smaller[i]; } } else { temp_n = b; temp_k = k-s; for(i=0;i<temp_n;i++) { temp[i]=Biger[i]; } } return Select_kth_Small(temp,temp_n,temp_k); } int main() { int arr[]={4,0,1,0,2,3}; int ans = Select_kth_Small(arr,6,3); cout<<"在数组arr[]={4,0,1,0,2,3}中,第3小的数是:"<<ans<<endl; return 0; }
这个代码多用了较多的辅助空间,为的是不改变原来的数组的元素的顺序。不知道这个代码有什么漏洞没有,大家帮帮找找。谢谢喽……
学习中的一点总结,欢迎拍砖哦^^
相关文章推荐
- 算法竞赛入门经典:第八章 高效算法设计 8.4快速排序应用之第k小的数
- 归并排序思想应用之----求数组中的逆序对
- 找包含N个元素的数组里第K大的元素(引申:快速排序、找中位数、找前K大的元素)的时间复杂度
- leetcode 27. Remove Element(C语言,快速排序思想,剔除数组中与目标值相等的数)20
- 20170927_快排应用_数组中寻找第K大的数字
- JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
- php数组快速排序
- 数据结构之二分法查找、快速排序思想与实现
- java数组应用之数组排序
- 快速排序的应用
- 数组快速排序、去重算法
- Java快速排序 分别以数组0位作为基准 和最后一位作为基准的排序演示
- JavaScript数组的快速克隆(slice()函数)和数组的排序、乱序和搜索(sort()函数)
- java 快速排序的思想及解释说明
- JavaScript数组的快速克隆(slice()函数)和数组的排序、乱序和搜索(sort()函数)
- 基于快速排序思想的随机排列的数组中找第k小的数
- 利用快速排序算法的思想,在一组随机排序数中,查找第K小的值。
- C/C++ 数组排序(平均时间复杂度 O(nlogn))归并、快速、堆、希尔之堆排序
- 数组与集合的应用之数组排序与查询(使用快速排序法)
- 快速排序之寻找第k小的值