算法复习(1) 堆排序
来源:互联网 发布:ubuntu安装mysql失败 编辑:程序博客网 时间:2024/05/17 02:16
堆是一种完全二叉树结构,以数组储存
堆的最后一层从左开始填充
对于元素个数为n的堆来说,高度为 floor(lgn)
对于给定下标i (从0开始),父节点,左儿子,右儿子分别为:
PARENT(i) return (i-1)>>1LEFT(i) return 2i+1RIGHT(i) return 2i+2
堆排序主体为3个函数:
Heapify、BuildHeap、Sort
Heapify用来保持某个特定节点及其所有子节点的最大/最小堆性质
BuildHeap用来将整个数组构建为最大/最小堆
Sort将数组排序,并毁坏最大/最小堆结构
//以最大堆为例//这里不做边界检查void Heapify(int * arr, int index, size){ int left = LEFT(index); int right = RIGHT(index); int largest = index; if (left < size && arr[left] > arr[index]) largest = left; else largest = index; if (right < size && arr[right] > arr[index]) largest = right; if (largest != index) { int t = arr[largest]; arr[largest] = arr[index]; arr[index] = t; Heapify(arr, largest, size); }}void BuildHeap(int* arr, int size){ int i = int(size/2) while(i--) Heapify(arr, i, size);}void Sort(int* arr, int size){ while(size >= 0) { int t = arr[0]; arr[0] = arr[size - 1]; arr[size-1] = t; Heapify(arr, 0, --size); }}
三个函数中关键在于BuildHeap是从最后一个拥有子节点的节点开始从下向上整理,而排序时每次都能以O(1)的代价找出最大值,再以O(lgn)代价恢复最大堆。
以最大/最小堆实现的最大/最小优先级队列是最大/最小堆的一个重要应用。
以最大堆为例
在之前的基础上添加了Maximum, ExtractMax, IncreaseKey(最小堆相应的为DecreaseKey), Insert 四个函数
int Maximum(int* arr){ return arr[0];}int ExtractMax(int* arr, int size){ int max = arr[0]; int t = arr[0]; arr[0] = arr[size-1]; arr[size-1] = t; Heapify(arr, 0, --size);}bool IncreaseKey(int* arr, int index, int size, int key){ if (arr[index] > key) return false; arr[index] = key; int i; while (i = PARENT(index) >= 0 && arr[i] < arr[index]) { int t = arr[i]; arr[i] = arr[index]; arr[index] = t; index = i; } return true;}//代码不检查边界,但是在这里边界检查非常重要bool Insert(int* arr, int size, int key){ arr[size] = INT_MIN; ++size; IncreaseKey(arr, size-1, size, key);}
最大/最小优先级队列在例如事件循环,工作调度中有显著的应用价值
但是对于最大/最小优先级队列,有一个问题:为什么在算法导论的介绍中不提供DecreaseKey(最大堆)和IncreaseKey(最小堆)?
就数据结构来说是完全可以做到的,代价也只是一次Heapify所带来的O(lgn)。我估计只是与最大/最小优先级队列的设计相违背所以不提供。实际工程应用中可能会有各种各样的需求,应当视实际情况重新设计。
若有不对,欢迎指出。
0 0
- 算法复习(1) 堆排序
- 算法导论复习(3) 堆排序
- 算法复习之堆排序
- 复习数据结构:排序算法(六)——堆排序
- 老老实实复习算法: 4 堆排序
- 算法导论堆排序的复习
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(1)-- 快速排序
- 复习排序-堆排序
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- 算法导论复习(1) 插入排序
- 温故知新,基础复习(二叉堆排序)
- 一步一步复习数据结构和算法基础-堆排序
- 排序算法(1):简单选择排序和堆排序
- 算法复习-插入排序1
- 排序算法复习(待)
- spring单例和多例详解。如何在单例中调用多例对象
- mysql中利用DATE_FORMAT方法 实现统计每日/每月的新增用户
- 一个错误信息提示页面
- 【jquery事件对象event】| jqeury bind 绑定事件与 unbind删除绑定事件| pageX pageY
- 第6周项目2-我的数组类
- 算法复习(1) 堆排序
- Search in Rotated Sorted Array
- Rotate Array--LeetCode
- MySQL执行计划解读
- web项目之BBS发布至新浪云配置修改以及sql语句修改问题小结
- Java设计模式——依赖倒转原则
- java中IO类的各种操作
- pat中文练习题:简单题:1001. 害死人不偿命的(3n+1)猜想
- 新人,报道(*^__^*)