• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
codezw
博客园    首页    新随笔    联系   管理    订阅  订阅
大根堆(Java实现)

实现大根堆的前提是满足完全二叉树(没看过完全二叉树的可以先去查阅一下),大根堆的规则:父节点永远大于它的子节点,实现小根堆只需将大于小于符号改变即可

举例:如数组{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,最近没怎么更新了,接下来慢慢补回来

 

posted on 2022-04-04 21:52  小小小哒大  阅读(661)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3