已知n个数字各不相同,求其中第k大的数是多少?(1≤k≤n≤10000)
这是一道简单的试题,我们完全可以套用常用的快速排序模型来解决,即对所有数字进行排序,然后取出第k大的数字输出即可,该算法的时间复杂度为O(nlog2n)
快速排序的基本思想关键在于不斷调整使分治点左边的数不大于(或不小于)分治点,右边的数不小于(或不大于)分治点。
一般快速排序,当找到一个分治点x,序列就以x为分治点,分成左右两部分。
假设每次找到的分治点接近中点,那么,其算法的时间代价大致为:n+n/2+n/4+n/8+…=2n.也就是说改进后的算法的时间复杂度为O(n).
namespace 求第k大的数
{
class Program
{
static int maxn = 10001;//序列长度的上限
static int[] arr = new int[maxn];//序列
static void Main(string[] args)
{
int k, n;//序列长度为n,被寻找的数的大小为k
Console.WriteLine("输入序列的长度");
n = int.Parse(Console.ReadLine().Trim());
Console.WriteLine("请输入序列:");
for (int i = 1; i <= n; i++)
{
arr[i] = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("您要寻找第几大的数?");
k = int.Parse(Console.ReadLine());
sort(1,n,k);
}
static void sort(int b_low, int b_high, int k)
{
int low = b_low, high = b_high;
int mid = (low + high) / 2;
int temp;
while (low < high)
{
while (low < mid)
{
if (arr[low] > arr[mid])
{
//swap(arr + low, arr + mid);
temp = arr[low];
arr[low] = arr[mid];
arr[mid] = temp;
mid = low;
low += 1;
break;
}
else
{
low++;
}
}
while (mid < high)
{
if (arr[high] < arr[mid])
{
//swap(arr + high, arr + mid);
temp = arr[high];
arr[high] = arr[mid];
arr[mid] = temp;
mid = high;
high -= 1;
break;
}
else
{
high--;
}
}
}
if (mid == k)
Console.WriteLine(arr[mid]);
else if (mid < k)
{
low = mid;
high = b_high;
sort(low, high, k);
}
else if (mid > k)
{
high = mid;
low = b_low;
sort(low, high, k);
}
}
}
}