1. 程式人生 > >完全二叉樹, 最大堆 , 堆排序

完全二叉樹, 最大堆 , 堆排序

system pub aps pack class 完全 節點 else 跳過

腦袋不夠用,所以記錄下來

python 版本 構建 最大堆

class Utils(object):
    @staticmethod
    def buildMaxHeap(l=None,heap_size=None):
        if heap_size is None:
            heap_size = len(l)
        for i in range(heap_size//2,0,-1):
            Utils.maxHeapify(heap_size,i,l)
            
    @staticmethod
    def maxHeapify(heap_size,rootIndex,l=None):
        left,right,largest = 2*rootIndex,2*rootIndex+1,rootIndex
        
        if left<=heap_size and l[left-1] > l[rootIndex-1]:
            largest = left
        if right<=heap_size and l[right-1] > l[largest-1]:
            largest = right
            
        if largest!=rootIndex:
            l[largest-1],l[rootIndex-1] = l[rootIndex-1],l[largest-1]
            if largest <= heap_size//2:
                Utils.maxHeapify(heap_size,largest,l)
        print(l)
        
if __name__ == '__main__':
    l = [10,9,3,2,4,6,5,7,8]
    print(l)
    Utils.buildMaxHeap(l)
    print(l)

改為 堆排序

class Utils(object):
    @staticmethod
    def buildMaxHeap(l=None,heap_size=None):
        if heap_size is None:
            heap_size = len(l)
        for i in range(heap_size//2,0,-1):
            Utils.maxHeapify(heap_size,i,l)
            
    @staticmethod
    def maxHeapify(heap_size,rootIndex,l=None):
        left,right,largest = 2*rootIndex,2*rootIndex+1,rootIndex
        
        if left<=heap_size and l[left-1] > l[rootIndex-1]:
            largest = left
        if right<=heap_size and l[right-1] > l[largest-1]:
            largest = right
            
        if largest!=rootIndex:
            l[largest-1],l[rootIndex-1] = l[rootIndex-1],l[largest-1]
            if largest <= heap_size//2:
                Utils.maxHeapify(heap_size,largest,l)
    @staticmethod
    def heapSort(l=None):
        Utils.buildMaxHeap(l)
        for i in range(len(l)-1,0,-1):
            l[0],l[i] = l[i],l[0]
            Utils.buildMaxHeap(l,i)
        
if __name__ == '__main__':
    l = [10,9,3,2,4,6,5,7,8]
    print(l)
#     Utils.buildMaxHeap(l)
    Utils.heapSort(l)
    print(l)

java 版

package com.ghc.starter.algorithm;
/*
這是一個排序算法集合的工具類
* */
public class SortUtils {
    public static int [] array = {10,9,3,2,4,6,5,7,8};

    // 完全二叉樹 --》最大堆--》堆排序
    public static void main(String [] args){
        printArray(array);
        buildMaxHeap(array,array.length);
        printArray(array);
        heapSort(array);
        printArray(array);
        array = new int[]{10,9,3,2,4,6,5,7,8};
        printArray(array);
        bubbleSort(array);
        printArray(array);
    }

    // 快速排序
    public static void quickSort(int [] array){

    }
    // 冒泡排序
    public static void bubbleSort(int [] array){
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array.length-i-1;j++){
                if(array[j]>array[j+1]){
                    swap(array,j,j+1);
                }
            }
        }
    }
    // 有格式的打印數組
    public static void printArray(int [] array){
        System.out.print("[");
        for(int i=0;i<array.length;i++){
            if(i!=array.length-1)
            System.out.print(array[i]+",");
            else System.out.println(array[i]+"]");
        }
    }
    // 堆排序 基於 下面 構建 最大堆
    public static void heapSort(int [] array){
        // 如果 數組只有一個元素或者為空則不用排序
        if(array==null || array.length<=1) return;
        // 否則開始 堆排序
        // 先 構建一個 最大堆
        buildMaxHeap(array,array.length);
        for(int i=array.length-1;i>0;i--){
            // 交換 堆頂與 最後位置的值,下一次 跳過 已經排好序的 位置
            swap(array,0,i);
            // 遞歸 重復構建 跳過 排好序的位置後的 最大堆
            buildMaxHeap(array,i);
        }
    }
    // 根據傳入的 數組 構建一個 最大堆 ,最大堆只能保證堆頂是最大值,那麽堆排序就是每次取最值後然後調整堆為最大堆
    public static void buildMaxHeap(int [] array,int heapSize){
        // 從 總節點數的 1/2 之一處開始 逆序 調整 最大堆
        for(int i=heapSize/2;i>0;i--){
            maxHeapify(array,heapSize,i);
        }
    }
    public static void maxHeapify(int [] array,int heapSize,int rootIndex){
        //左葉子結點
        int l = 2*rootIndex;
        // 右葉子結點
        int r = l+1;
        // 調整需要的最大值指向
        int largest = rootIndex;
        //如果 左葉子結點比父節點要大 ,那麽修改 largest 指向為 l
        if(l<=heapSize && array[l-1]>array[rootIndex-1]){
            largest = l;
        }
        //如果 右葉子結點比父節點要大 ,那麽修改 largest 指向為 r
        if(r<=heapSize && array[r-1]>array[largest-1]){
            largest = r;
        }
        // 如果 最大值不是 父節點,那麽交換 最大值指向與父節點的位置
        if(largest!=rootIndex){
            swap(array,largest-1,rootIndex-1);
            if(largest<=heapSize/2){
                // 如果該父節點有子節點,那麽對 子節點也遞歸做 最大堆調整
                maxHeapify(array,heapSize,largest);
            }
        }

    }
    // 交換 數組中的值
    public static void swap(int [] array,int i,int j){
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

完全二叉樹, 最大堆 , 堆排序