排序算法八:堆排序

来源:互联网 发布:lol解封软件 编辑:程序博客网 时间:2024/06/07 12:40

堆排序

堆排序(Heap Sort),顾名思义,借助于堆的形式来实现排序。这个堆分为大根堆和小根堆两种,大根堆用来实现从小到大的顺序排序,小根堆则用来实现从大到小的降序排序。每构造出一个大(小)根堆,即获得了一个最优值(根节点),将该根节点去掉,剩余的继续进行构造堆的做法,获得剩余元素的最优值,重复之前的做法,直到全部完成排序为止。
堆排序的难点即在于堆的构成和实现。以大根堆为例,先将一个无序队列看做一个堆。其中,坐标 0 元素为根元素,1、2坐标元素为 0 元素的子元素,3、4坐标元素为 1 元素的子元素,5、6坐标元素为 2 坐标的子元素,以此类推。然后,从根堆的最底端子节点(非叶子节点),也即中间节点开始分别与其子节点进行比较,将其中的大者作为该子节点的元素。逐个排查所有的非叶子节点,直到根节点为止,将最大元素赋给根节点。这样经过排查,即找到了堆的最大值。将该最大值与堆的末端节点对换,重复上述过程,对剩余的元素重新进行堆的构造和最优值的对换,直到全部排序完成为止。
Java代码如下:
/** * 大根堆排序:实现顺序排序 * @param data * @param i */private static void heapSort(int[] data, int length) {//递归结束if (1 == length) {return;}//获取最底端的非叶子节点的坐标int mid = (length -1)>>1;//构造堆//左右子节点的坐标int left = 0;int right = 0;for (int i = mid; i >= 0; i--) {//与左孩子节点比较left = (i+1)<<1;if (left<=length && data[i]<data[left]) {swap(data,i,left);}//与右孩子节点比较right = left -1;if (right<=length && data[i]<data[right]) {swap(data,i,right);}}//将最大值与队列最后一个元素对换swap(data, 0, length);//递归上面的过程heapSort(data, length - 1);}/** * 数组内 i 坐标元素与 j 坐标元素互换 * @param data * @param i * @param j */private static void swap(int[] data, int i, int j) {int temp = data[i];data[i] = data[j];data[j] = temp;}

该算法的初始参数为数据data和数据末点坐标 data.length-1。因为只有最底端的非叶子节点的叶子节点有可能出现越界情况,因此,这里可以做一点改进,减少不必要的越界判断。
代码如下:
/** * 大根堆排序:实现顺序排序 * @param data * @param i */private static void heapSort2(int[] data, int length) {//递归结束if (1 == length) {return;}//获取最底端的非叶子节点的坐标int mid = (length -1)>>1;//构造堆//左右子节点的坐标int left = 0;int right = 0;//最底端的非叶子节点比较int i = mid;left = (i+1)<<1;if (left<=length && data[i]<data[left]) {swap(data,i,left);}right = left -1;if (right<=length && data[i]<data[right]) {swap(data,i,right);}i--;//剩余非叶子节点比较for (; i >= 0; i--) {//与左孩子节点比较left = (i+1)<<1;if (data[i]<data[left]) {swap(data,i,left);}//与右孩子节点比较right = left -1;if (data[i]<data[right]) {swap(data,i,right);}}//将最大值与队列最后一个元素对换swap(data, 0, length);//递归上面的过程heapSort(data, length - 1);}/** * 数组内 i 坐标元素与 j 坐标元素互换 * @param data * @param i * @param j */private static void swap(int[] data, int i, int j) {int temp = data[i];data[i] = data[j];data[j] = temp;}

0 0