快排思想求中位数

由于快速排序每一轮都可以将一个元素正确的归位,所以我们可以利用快速排序的思想来定位中位数。

1)我们就以数组的arr[0]为基准参照,如果第一轮快排过后,arr[0]的位置恰好被归位到arr.Length/2,则arr[0]肯定就是中位数;

2)如果arr[0]归位后,位置小于arr.Length/2(假如是i),则中位数肯定在arr[i+1]到arr[arr.Length-1]之间。

3)如果arr[0]归位后,位置大于arr.Length/2(假如是j),则中位数肯定在arr[0]到arr[j-1]之间。

4)递归即可。

 1 using System;
 2 using System.Diagnostics;
 3 using System.Linq;
 4 using System.Threading;
 5 
 6 namespace MiddleNumber
 7 {
 8     class Program
 9     {
10         //static int[] _arr = { 4, 5,10, 15, 19, 14, 10, 10 };
11         static Stopwatch _stopwatch = new Stopwatch();
12         static void Main(string[] args)
13         {
14             int[] _arr = GetNumbers(40000);
15             _stopwatch.Start();
16             var arrList = _arr.ToList();
17             arrList.Sort();
18             Console.WriteLine(arrList[_arr.Length / 2]);
19             _stopwatch.Stop();
20             Console.WriteLine("sort方法后去中间位置的数,毫秒数{0}",_stopwatch.ElapsedMilliseconds);
21             _stopwatch.Reset();
_stopwatch.Start();
22 Console.WriteLine(GetMiddleNum(_arr, 0, _arr.Length / 2)); 23 _stopwatch.Stop(); 24 Console.WriteLine("快排求中位数,毫秒数{0}",_stopwatch.ElapsedMilliseconds); 25 Console.ReadKey(); 26 } 27 //利用快速排序的思想寻找中位数,快排的每一轮可以完全确定一个元素的归位。 28 private static int GetMiddleNum(int[] arr, int idx, int middle) 29 { 30 int i = 0; 31 int j = arr.Length - 1; 32 while (true) 33 { 34 while (i != j && arr[j] >= arr[0]) 35 j--; 36 while (i != j && arr[i] <= arr[0]) 37 i++; 38 if (i != j) 39 Exchange(ref arr[i], ref arr[j]); 40 if (i == j) 41 { 42 if (i != 0) 43 Exchange(ref arr[i], ref arr[0]); 44 if (i + idx == middle) 45 return arr[i]; 46 else if (i + idx > middle) 47 return GetMiddleNum(arr.Take(i).ToArray(), idx, middle); 48 else 49 return GetMiddleNum(arr.Skip(i + 1).ToArray(), i + 1 + idx, middle); 50 } 51 } 52 } 53 //注意这里有个陷阱: 54 //var t = new int[] {10}; //只有一个元素10 55 //Exchange(ref t[0],ref t[0]); 56 //这样的话,结果t[0]=0;而不再是10,达不到交换的目的;自己想想为什么 57 static private void Exchange(ref int a, ref int b) 58 { 59 a = a ^ b; 60 b = b ^ a; 61 a = a ^ b; 62 } 63 //产生随机数 64 private static int[] GetNumbers(int x) 65 { 66 var arr = new int[x]; 67 for (int i = 0; i < x; i++) 68 { 69 Thread.Sleep(100); 70 arr[i] = new Random().Next(1, x); 71 } 72 return arr; 73 } 74 } 75 }

但是测出来时间差别不大,不知道为何。100000个随机数,时间也一样。

 

转载于:https://www.cnblogs.com/mulei/p/4082366.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值