最直观的解法,排序之后取下标为k的值即可。

但是此处采取的方法为类似快速排序分块的方法,利用一个支点将序列分为两个子序列(支点左边的值小于支点的值,支点右边大于等于支点的值)。

如果支点下标等于k,则支点就是查找的值,如果支点的下标大于k,则在左子序列里继续寻找,如果支点下标小于k,则继续在支点右子序列里面继续寻找第(k-支点下标)小的值。

c#实现算法如下:

 public class FindSpecialOrderElement<T> where T : IComparable<T>
{
public T FindElementWithOrder(T[] array, int startIndex, int endIndex, int order)
{
int pivot = Partition(array, startIndex, endIndex);
//pivot支点为第(pivot-startIndex+1)小的值
int pivotOrder = pivot - startIndex + ;
if (pivotOrder == order)
{ return array[pivot]; }
else if (pivotOrder > order)
{
return FindElementWithOrder(array, startIndex, pivot - , order);
}
else//pivotOrder < order
{
return FindElementWithOrder(array, pivot + , endIndex, order - pivotOrder);
}
}
public static int Partition(T[] array, int leftIndex, int rightIndex)
{
//leftIndex的位置空出来了
T pivotValue = array[leftIndex];
//将所有<pivotValue的值移动到pivotValue的左边(不稳定排序,因为相等值得相对位置可能被此步骤改变)
//将所有>=pivotValue的值移到右边
//移动的结果就是所有<pivotValue的值都在pivotValue的左边,>=它的都在右边
//记录之后pivotValue所在位置,返回该位置,完成一次分区划分。
while (leftIndex < rightIndex)
{
//因为是leftIndex先空出来位置,所以第一步要从右侧rightIndex向左寻找小于pivotValue的数值位置
while (leftIndex < rightIndex && array[rightIndex].CompareTo(pivotValue) >= ) rightIndex--;
//将找到的小于pivotValue的位置的元素放到空出的leftIndex位置,leftIndex++
if (leftIndex < rightIndex) array[leftIndex++] = array[rightIndex];
//leftIndex向右寻找>=pivotValue的值的位置
while (leftIndex < rightIndex && array[leftIndex].CompareTo(pivotValue) < ) leftIndex++;
//将找到的>=pivotValue的位置的leftIndex元素放到上一步空出的rightIndex位置
//此时leftIndex所在位置变成待插入位置,重新回到外圈循坏的初始状态
if (leftIndex < rightIndex) array[rightIndex--] = array[leftIndex];
}
//最后while循环结束的位置就是leftIndex==rightIndex,并且这个位置是空出来的,正好把pivotValue放到这个位置
//这就是轴的概念,轴两边的值时由轴正好分开的,一边小于轴,一边大于等于轴
array[leftIndex] = pivotValue;
return leftIndex;
} }

方法调用方法:

 static void Main(string[] args)
{
FindSpecialOrderElement<int> ESOE = new FindSpecialOrderElement<int>();
int[] data1 = new int[] { , , , , , , , , , };
Console.WriteLine();
data1.ToList<int>().ForEach(i => Console.Write("{0},", i));
int e = ESOE.FindElementWithOrder(data1, , data1.Length - , );
Console.WriteLine("Find the 4th small element:{0}", e); int[] data2 = new int[] { , , , , , , , , , };
Console.WriteLine();
data2.ToList<int>().ForEach(i => Console.Write("{0},", i));
int f = ESOE.FindElementWithOrder(data2, , data1.Length - , );
Console.WriteLine("Find the 7th small element:{0}", f);
Console.ReadKey();
}

作者:Andy Zeng

欢迎任何形式的转载,但请务必注明出处。

http://www.cnblogs.com/andyzeng/p/3695478.html

顺序统计:寻找序列中第k小的数的更多相关文章

  1. 计算序列中第k小的数

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046399.html 使用分治算法,首先选择随机选择轴值pivot,并使的序列中比pivot ...

  2. ch1_5_2求无序序列中第k小的元素

    import java.util.Arrays; import java.util.PriorityQueue; public class ch1_5_2求无序序列中第k小的元素 { public s ...

  3. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  4. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  5. 选择问题(选择数组中第K小的数)

    由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小 ...

  6. Leetcode 668.乘法表中第k小的数

    乘法表中第k小的数 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字. 例 1: 输入 ...

  7. Java实现 LeetCode 668 乘法表中第k小的数(二分)

    668. 乘法表中第k小的数 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字. 例 ...

  8. 每天一道算法题(32)——输出数组中第k小的数

    1.题目 快速输出第K小的数 2.思路 使用快速排序的思想,递归求解.若键值位置i与k相等,返回.若大于k,则在[start,i-1]中寻找第k大的数.若小于k.则在[i+1,end]中寻找第k+st ...

  9. 寻找数列中第k大的数算法分析

    问题描述:给定一系列数{a1,a2,...,an},这些数无序的,现在求第k大的数. 看到这个问题,首先想到的是先排序,然后直接输出第k大的数,于是得到啦基于排序的算法 算法一: #include&l ...

随机推荐

  1. Appium ——Android KEYCODE键值:

    Python下语法: driver.keyevent(键值) 电话按键: 键名 描述 键值 KEYCODE_CALL 拨号键 5 KEYCODE_ENDCALL 挂机键 6 KEYCODE_HOME ...

  2. ajax 和 mock 数据

    ajax ajax是一种技术方案,但并不是一种新技术.它依赖的是现有的CSS/HTML/Javascript,而其中最核心的依赖是浏览器提供的XMLHttpRequest对象,是这个对象使得浏览器可以 ...

  3. 洛谷 P1781 宇宙总统:sort(string)

    题目描述 地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统. 输入输出格式 输入格式: 第一行为一个整数n,代表竞选 ...

  4. C#通过gridview导出excel

    [CustomAuthorize]        public FileResult ExportQuestionCenterExcel(SearchBaseQuestion search)      ...

  5. Alpha冲刺——第一天

    Alpha第一天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  6. android入门 — ListView

    ListView主要是用来解决大量数据展示的问题,它的用途很广泛,几乎所有的app都会用到,比如说知乎.今日头条.微博.通讯录等. ListView允许用户通过上下滑动的方式将屏幕外的数据滚动到屏幕中 ...

  7. [C/C++] C++类对象创建问题

    CSomething a();// 没有创建对象,这里不是使用默认构造函数,而是定义了一个函数,在C++ Primer393页中有说明. CSomething b(2);//使用一个参数的构造函数,创 ...

  8. matlab函数列表(A~Z)【转】

    A a abs 绝对值.模.字符的ASCII码值acos 反余弦acosh 反双曲余弦acot 反余切acoth 反双曲余切acsc 反余割acsch 反双曲余割align 启动图形对象几何位置排列工 ...

  9. K-means聚类算法与EM算法

    K-means聚类算法 K-means聚类算法也是聚类算法中最简单的一种了,但是里面包含的思想却不一般. 聚类属于无监督学习.在聚类问题中,给我们的训练样本是,每个,没有了y. K-means算法是将 ...

  10. 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法

    题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...