1

最近在刷leetcode和牛客网上的算法题,正处于癫狂状态。。。所以,突然想记下来自己编译通过的代码,以备日后不时之需,至于之前没来得及记下的那些刷过的题目,就。。。。。这样吧,我也懒得回头重做一遍那些题目。

代码

要求:

对于一个int数组,请编写一个堆排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:

[1,2,3,5,2,3],6
[1,2,2,3,3,5]

程序:

class HeapSort {
public:
    int* heapSort(int* A, int n) {
        // write code here
        if(n<2){
            return A;
        }
        int temp;
        heapBuild(A,n);
        for(int j=n;j>1;j--){
            temp=A[j-1];
            A[j-1]=A[0];
            A[0]=temp;
            heapAdjust(A,1,j-1);
        }
        return A;
    }
    
private:
    void heapAdjust(int* A, int i, int size){
        if(i<=size/2){
            int max=i;
            int lchild = i*2;
            int rchild = i*2+1;
            int temp;
            if(lchild<=size&&A[lchild-1]>A[max-1]){  //第一次编译没通过就跪在这里了,忘记应该选择父节点、左孩子节点、右孩子节点三者中的最大值。
                max=lchild;
            }
            if(rchild<=size&&A[rchild-1]>A[max-1]){
                max=rchild;
            }
            if(max!=i){
                temp = A[max-1];
                A[max-1] = A[i-1];
                A[i-1] = temp;
                heapAdjust(A,max,size);
            }
        }
    }
    
    void heapBuild(int* A,int size){
        for(int i=size/2;i>=1;i--){
            heapAdjust(A,i,size);
        }
    }
    
};

跪点

  • 每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)

  • 在《算法导论》里,数组的下标是从1开始的,节点的父节点、左右子节点之间的关系:PARENT(i)=i/2,LEFT(i) = 2*i,RIGHT(i) = 2*i+1。一般题目的数组都是从下表0开始的,需要微调。

参考

1.堆排序原理及算法实现(最大堆)
2.《算法导论》读书笔记之第6章 堆排序


jack2wang
753 声望27 粉丝