一、C 程序实现:
/******************************************************* * Description: 堆排序算法 * Author: shujuxiong * Version: 1.0 * Time: 2018-06-25 *******************************************************/ #include <stdio.h> //函数:打印数组 void PrintDataArray(int a[], int n) { for(int i=0; i<n; i++) printf("%d ",a[i]); printf("\n"); } //堆排序问题一:如何调整一个大顶堆? void HeapAdjust(int a[], int root, int n) { int tmp = a[root]; int child = 2*root+1; //左孩子节点的位置 while(child<n) { //找出较大的那个孩子节点的位置 if(child+1<n && a[child]<a[child+1]) child++; //如果较大的孩子节点大于父节点,则用较大的孩子节点替换父节点,并重新设置下一个需要调整的父节点与子节点 if(a[root]<a[child]) { a[root] = a[child]; root = child; child = 2*root+1; } else break; //将调整前父节点的值赋值给调整后的位置 a[root] = tmp; } } //堆排序问题一:如何初始化建堆? void HeapBuild(int a[], int n) { //从最后一个有孩子节点的位置开始调整,最后一个有孩子节点的位置为(n-1)/2 for(int i=(n-1)/2; i>=0; i--) { HeapAdjust(a, i, n); } } //堆排序,结果是递增有序数组 void HeapSort(int a[], int n) { //初始化建堆,结果是堆有序数组 HeapBuild(a, n); //从最后一个节点开始调整 for(int i=n-1; i>=0; i--) { //交换堆顶元素和最后一个元素 int tmp = a[0]; a[0] = a[i]; a[i] = tmp; //每次交换后都要进行调整 HeapAdjust(a, 0, i); } PrintDataArray(a, n); } //测试用例 int main() { int a[] = {3,1,7,5,2,4,9,6}; int len = sizeof(a)/sizeof(a[0]); HeapSort(a, len); return 0; }
运行结果:
二、Java 程序实现:
/** * @description: 堆排序算法 * @author: shujuxiong * @version: 1.0 * @date: 2018-06-25 */ public class HeapSort { //堆排序问题二:如何调整一个大顶堆? public static void heapAdjust(int[] a, int root, int n) { int tmp = a[root]; int child = 2*root+1; //左孩子节点的位置 while(child < n) { //找到较大的孩子节点的位置 if(child+1 < n && a[child+1] > a[child]) child++; //若父节点小于较大的孩子节点,则用较大的孩子节点的值替换父节点,并重新设置下一个需要调整的父节点和孩子节点 if(a[root] < a[child]) { a[root] = a[child]; root = child; child = 2*root+1; } else break; //将调整前父节点的值赋值给调整后的位置 a[root] = tmp; } } //堆排序问题一:如何初始化一个大顶堆? public static void heapBuild(int[] a, int n) { //从最后一个有孩子节点的位置开始调整 for(int i=(n-1)/2; i>=0; i--) heapAdjust(a, i, n); } //堆排序,结果是一递增的有序数组 public static void sort(int[] a, int n) { //初始化建堆,结果是堆有序素组 heapBuild(a, n); //从最后一个节点开始调整 for(int i=n-1; i>=0; i--) { //交换堆顶元素和最后一个元素 int tmp = a[0]; a[0] = a[i]; a[i] = tmp; //每次交换后都要重新调整堆 heapAdjust(a, 0, i); } } //方法:打印数组 private static void printDataArray(int[] a) { int N = a.length; for(int i = 0; i < N; i++) System.out.printf("%d ",a[i]); System.out.printf("\n"); } //测试用例 public static void main(String[] args) { int[] arr = {3,1,7,5,2,4,9,6}; int N = arr.length; sort(arr, N); printDataArray(arr); } }
运行结果:
三、Python 程序实现
# -*- coding: utf-8 -*- """ Description: 堆排序算法 Author: shujuxiong Version: 1.0 Date: 2018-06-25 """ import copy ##堆排序问题二:如何调整一个大顶堆? def heapAdjust(relist, root, n): tmp = relist[root] child = 2*root+1 #左孩子节点的位置 while(child<n): #找到较大孩子节点的位置 if(child+1<n and relist[child+1]>relist[child]): child = child+1 #若父节点小于较大的孩子节点,则用较大的孩子节点替换父节点,并重新设置下一个需要调整的父节点和子节点 if(relist[root] < relist[child]): relist[root] = relist[child] root = child child = 2*root+1 else: break #将调整前父节点的值赋值给调整后的位置 relist[root] = tmp ##堆排序问题一:如何初始化一个大顶堆 def heapBuild(relist, n): #从最后一个有孩子节点的位置开始调整 for i in range((n-1)//2, -1, -1): heapAdjust(relist, i, n) ##堆排序,结果是一个递增有序数组 def heapSort(relist): N = len(relist) #初始化建堆,结果是堆有序数组 heapBuild(relist, N) #从最后一个元素开始调整 for i in range(N-1, -1, -1): tmp = relist[0]; relist[0] = relist[i] relist[i] = tmp #每次调整后都要重新调整堆 heapAdjust(relist, 0, i) return relist ##测序用例 def main(): mylist = [3,1,7,5,2,4,9,6] print(heapSort(copy.copy(mylist))) if __name__=='__main__': main()
运行结果: