博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
堆排序
阅读量:4577 次
发布时间:2019-06-08

本文共 3521 字,大约阅读时间需要 11 分钟。

 堆排序

static void Main(string[] args){    //产生随机序列    var rand = new Random();    List
sequence = new List
(); int length = 50; int count = 0; //以堆的形状输出数值 int level = (int)(Math.Log(length) / Math.Log(2)) + 1; for (int i = 0; i < level; i++) { string pre = new string(' ', (int)Math.Pow(2, level - i - 1) - 1); string inter = new string(' ', (int)Math.Pow(2, level - i) - 1); Console.Write(pre); for (int k = 0; k < Math.Pow(2, i) && count < length; k++, count++) { sequence.Add(rand.Next() % 10); Console.Write("{0}" + inter, sequence[count]); } Console.WriteLine(); } //使用堆排序 HeapSort(sequence); //以堆的形状输出数值 Console.WriteLine(); length = sequence.Count; count = 0; for (int i = 0; i < level; i++) { string pre = new string(' ', (int)Math.Pow(2, level - i - 1) - 1); string inter = new string(' ', (int)Math.Pow(2, level - i) - 1); Console.Write(pre); for (int k = 0; k < Math.Pow(2, i) && count < length; k++, count++) { Console.Write("{0}" + inter, sequence[count]); } Console.WriteLine(); } Console.Read();}//堆排序,时间复杂度O(nlg(n))static void HeapSort(List
sq){ //创建最大堆(节点上的值大于叶子节点的值) //时间复杂度O(n) BuildMaxHeap(sq); //最大堆的根节点为最大值,将最大值放在数组最后,同时将未维护的堆大小-1 //然后重新维护最大堆 for (int i = sq.Count - 1; i > 0; i--) { var temp = sq[i]; sq[i] = sq[0]; sq[0] = temp; heapSize--; MaxHeapify(sq, 0); }}//当前堆需要维护的大小static int heapSize = 0;//构建最大堆static void BuildMaxHeap(List
sq){ heapSize = sq.Count; //对每一个非叶子节点进行维护,从最后一个非叶子节点开始 for (int i = heapSize / 2; i >= 0; i--) { MaxHeapify(sq, i); }}//在假定叶子节点为最大堆的情况下,维护最大堆,时间复杂度O(lg(n))static void MaxHeapify(List
sq, int i){ int l = (i + 1) << 1 - 1; int r = (i + 1) << 1; int large = 0; if (l < heapSize && sq[l] > sq[i]) large = l; else large = i; if (r < heapSize && sq[r] > sq[large]) large = r; if (large != i) { var temp = sq[i]; sq[i] = sq[large]; sq[large] = temp; MaxHeapify(sq, large); }}

 

 优先队列与堆排序

优先队列用于维护一维元素构成的结合。其中,最大优先队列支持一下操作:

  1. Insert(S, x),将元素x插入S集合中
  2. Maximum(S),返回S集合中最大关键字
  3. ExtractMax(S),去掉S集合中最大关键字的项
  4. IncreaseKey(S, x, k),将x的值增加为到k,一般假设k>x

明显使用堆可以维护一个优先队列。在一个维护好的最大堆中(非排序后,而是在BuildMaxHeap后),各种操作可以有如下实现。

操作1:在最后插入一个极小值,然后使用操作4,则驾到x

//sq为最大堆static void MaxHeapInsert(List
sq, int key){ heapSize++; sq.Add(int.MinValue); HeapIncreaseKey(sq, heapSize - 1, key);}

操作2:直接返回S[0];

//sq为最大堆static int HeapMaximum(List
sq){ return sq[0];}

操作3:使用堆排序中的HeadSort变体,将第一个最大值取出

//sq为最大堆static int HeapExtractMax(List
sq){ if (heapSize < 1) throw new Exception("heap underflow"); int max = sq[0]; sq[0] = sq[heapSize]; heapSize--; //移除最后一个元素 sq.RemoveAt(heapSize); //重新维护最大堆 MaxHeapify(sq, 0); return max;}

操作4:替换后,与父节点递归比较

//sq为最大堆static void HeapIncreaseKey(List
sq, int i, int key){ if (key < sq[i]) throw new Exception("new key must greater than current"); sq[i] = key; // 父节点为(i+1)>>1-1 //逐一与父节点比较 while (i > 1 && sq[(i + 1) >> 1 - 1] < sq[i]) { var temp = sq[i]; sq[i] = sq[(i + 1) >> 1 - 1]; sq[(i + 1) >> 1 - 1] = temp; }}

 

 

 

转载于:https://www.cnblogs.com/qiusuo/p/5211101.html

你可能感兴趣的文章
钢材销售系统1
查看>>
CSS居中布局总结
查看>>
NET_.NET深入体验与实战精要 第一章
查看>>
Android toolbar menu 字体点击样式
查看>>
实验一
查看>>
CCF——相邻数对201409-1
查看>>
JsBom
查看>>
re模块的使用
查看>>
继承和对象指针
查看>>
tkinter第三章(单选和多选)RadioButton CheckButton
查看>>
fedora yum源设置
查看>>
Linux服务器redhat配置本地yum源
查看>>
C#类型转换
查看>>
SignalRMvc的简单例子
查看>>
python 元组 【基本使用功能】
查看>>
ecplise 使用快捷键
查看>>
微信emoji表情编码 、MySQL 存储 emoji 表情符号字符集
查看>>
Netty心跳之IdleStateHandler
查看>>
hash小结
查看>>
动态调用WebService
查看>>