堆的简述以及堆排序
来源:互联网 发布:17年机械行业数据 编辑:程序博客网 时间:2024/06/18 10:29
堆的定义:
堆是一个数组,是一个近似的完全二叉树(算法导论的定义,不同的书籍对XX二叉树有着不同的定义,请注意),即除了最低层外,该树是完满的,并且最底层是从左到右依次填充。
通过定义可以看出,堆数组是没有“洞的”,每个有效数字都是紧挨着的!
堆的性质:
最大堆值的是对于当前下标i,有left(i)和right(i)两棵子树,且保证下标i对应的值比两棵子树所有的值都大。
最小堆与上述定义相反。
构造堆:
为了构造堆,我们需要对所有非叶子节点(叶子结点没有子节点,满足堆的性质),自底向上地逐个进行处理,要维护好堆的性质。
堆排序:
对一个满足堆性质的数组(即堆),每次取出根节点与最后一个结点交换,然后重新对根节点维护堆的性质,最后堆数组的大小要减一,因为被交换到后面的数组是有序的,不符合堆的性质。
伪代码:
heapSort()
1. 对数组进行堆的构造
2. for i=最后一个结点的下标 downto 1
3. 交换A[0]和A[i]
4. 堆的有效长度减1
5. 对根结点进行堆的维护
具体代码:
import java.util.Arrays;/*根节点下标为0*/public class Heap {private int[] arr;private int arr_length; //数组长度private int size; //堆的有效长度,即arr[0-size]满足堆的性质public Heap(int[] arr){this.arr = arr;arr_length = arr.length;size = arr.length;}//获得左子节点下标private int getLeftChild(int index){return 2*index+1;}private int getRightChild(int index){return 2*index+2;}//获得父节点下标private int getParent(int index){return (index-1)/2;}//维护最大堆的性质public void max_heapify(int index){int left = getLeftChild(index);int right = getRightChild(index);int largest = index; //largest记录index、它的左子节点、它的右子节点对应值最大的下标if(left<size&&arr[left]>arr[index]){largest = left;}else largest = index;if(right<size&&arr[right]>arr[largest]){largest = right;}//若largest不是index,交换后,arr[largest]变小了,可能会破坏了堆的性质,所以要继续对此维护if(largest!=index){int temp = arr[largest];arr[largest] = arr[index];arr[index] = temp;max_heapify(largest);}}//构造最大堆public void build_heap(){//从数组最后一个节点的父节点的右边第一个节点开始,到最后一个节点都是叶节点for(int i=getParent(size-1);i>=0;i--){max_heapify(i);}}//堆排序public void heapSort(){build_heap();//先对数组进行堆的构造for(int i=size-1;i>=1;i--){int temp = arr[0];arr[0] = arr[i];arr[i] = temp;size--; //易错点,堆数组有效个数减一,因为交换过后,i后面的数都是升序的,不符合最大堆的性质max_heapify(0);}}public static void main(String[] args){int[] arr = new int[(int)(Math.random()*50)];for(int i=0;i<arr.length;i++){arr[i] = (int)(Math.random()*50);}Heap heap = new Heap(arr);heap.heapSort();System.out.println(Arrays.toString(arr));}}
阅读全文
1 0
- 堆的简述以及堆排序
- 堆以及堆排序
- 堆的构建以及利用堆排序
- 堆数据结构的实现以及堆排序
- 堆的简介以及堆排序
- 堆以及堆排序实现
- 调整堆以及堆排序
- 堆排序以及归并排序的理解
- 堆的建立、删除、插入操作以及堆排序
- 最大二叉堆的建立以及最大堆排序
- 堆排序以及二叉堆的一些操作
- 堆的应用:topk问题以及堆排序
- 大顶堆以及堆排序
- 关于堆排序建堆时间以及堆排序的分析之暑假学习记录
- 堆的建立&堆排序
- c++实现堆类以及堆排序
- 堆排序,以及stl中的堆应用
- Java实现堆以及堆排序
- Linux下ffmpeg的安装过程
- Java面试-关于线程方面的知识迷惑
- 03.10 Xshell优化与远程连接故障排查
- 简易在线留言板(下)——树洞留言板
- PAT+乙1005. 继续(3n+1)猜想
- 堆的简述以及堆排序
- 剑指offer | 训练题53:字流中第一个不重复的字符
- Linux下设置swap(虚拟内存区)
- c++ 左偏树简析 猴王例题讲解
- iptables详解
- HDU 3652 B-number (数位DP)
- c语言 什么时候需要动态分配内存?
- 1-9三个三位数
- 剑指offer——替换空格