1. 程式人生 > 其它 >大根堆

大根堆

實現大根堆的前提是滿足完全二叉樹(沒看過完全二叉樹的可以先去查閱一下),大根堆的規則:父節點永遠大於它的子節點,實現小根堆只需將大於小於符號改變即可

舉例:如陣列{0,1,2,3,4,5,6};

其中對於任意一個節點K(除了根節點)其父節點為(K-1)/2,子節點2*K+1,2*K+2;

最後一個非葉子節點為:(heap_size-2)/2

主要演算法:

向上調整:用於資料的插入

向下調整:用於建堆和刪除資料和取堆頂(取堆頂是一種特殊的刪除)

原始碼如下:

package javaee.first;

import java.util.Arrays;
import java.util.Scanner;

/* * 大根堆小根堆的實現 * */ public class first { public static void main(String[] args) { Heap heap = new Heap(); int flag = 1; while (flag == 1) { System.out.println("請輸入你想完成的操作(請先建立堆):"); System.out.println("建立堆:creat"); System.out.println("插入資料:insert"); System.out.println(
"刪除資料:del"); System.out.println("輸出堆:print"); System.out.println("結束程式:over"); Scanner sc = new Scanner(System.in); String comm = sc.next(); switch (comm) { case "creat": creat(heap);
break; case "insert": inst(heap); break; case "del": del(heap); break; case "print": print(heap); break; case "over": flag = 0; } } } public static void creat(Heap heap) { Scanner sc = new Scanner(System.in); int n; System.out.print("輸入堆的大小和資料:"); n = sc.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); } heap.buildHeap(a); } public static void print(Heap heap) { heap.Print(); System.out.println(""); } public static void inst(Heap heap) { System.out.println("請輸入你要插入的數:"); int n; Scanner sc = new Scanner(System.in); n = sc.nextInt(); heap.push(n); } public static void del(Heap heap) { System.out.println("請輸入你想刪除的資料的下標:"); int n; Scanner sc = new Scanner(System.in); n = sc.nextInt(); heap.poll(n); } }
package javaee.first;


import java.util.Arrays;

public class Heap {
    int[] arr = new int[100];
    int heap_Size = 0;
    /*
     * push實現大根堆資料的插入,arr.length(heap_Size)表示非葉子節點
     * */
    public void push(int value) {
         arr = Arrays.copyOf(arr,arr.length+1);   //實現陣列的擴容
         arr[heap_Size++] = value;
         adjustUp((heap_Size-2)/2);
    }
    /*
    * poll實現大根堆的堆頂的刪除
    * */
    public void poll(int d){
        swap(d,heap_Size-1);   //交換資料
        heap_Size--;
        adjustDown(d);
    }
    /*
    * 建立大根堆
    * */
    public void buildHeap(int[] arr1){
        arr = arr1;
        heap_Size = arr.length;
        for (int i = (arr.length-2)/2; i >=0; i--) {
            adjustDown(i);
        }
    }
    /*
    * swap()實現資料的交換
    * */
    void swap(int i, int j) {
        int t;
        t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
    /*
    *向下調整
    * */
    public void adjustDown(int k){
        if(heap_Size == 1||k> (heap_Size-2)/2)
            return;
        int l = 2*k + 1,r = 2*k+2,largest = l;
        if(r < heap_Size && arr[r] > arr[l])
            largest = r;
        if(arr[largest] > arr[k])
        {
            swap(largest,k);
            adjustDown(largest);
        }
    }
    /*
    *向上調整
    * */
    public void adjustUp(int i){
        if(i < 0)
            return ;
        int l = 2*i + 1,r = 2*i+2,largest = l;
        if(r < heap_Size && arr[r] > arr[l])
            largest = r;
        if(arr[largest] > arr[i])
        {
            swap(largest,i);
            adjustUp((i-1)/2);
        }
    }
    public void sort(){
        for (int i = 0; i < arr.length; i++) {
            poll(0);
        }
    }
    //堆的輸出
    public void Print(){
        for (int i = 0; i < heap_Size; i++) {
            System.out.printf("%d ",arr[i]);
        }
    }
}

當菜鳥的第六天2022-04-04,最近沒怎麼更新了,接下來慢慢補回來