java数据结构:堆,PriorityQueue小顶堆,大顶堆翻转(亲手实战)

堆和树

数据结构中有两个概念很相似,比如树的数据结构,还有一种结构叫“堆”,堆是一种特殊的树,min heap是小顶堆;max heap是大顶堆
树和堆主要区别

  • 树分左右,堆一般不分左右
  • 用途不同,堆主要用于优先队列;而树的用途更加广泛

堆=完全二叉树+排序的规则
堆和树有什么区别?堆为什么要叫堆,不叫树呢?

如下用小顶堆(比起一般的数组)速度提升了5倍!!!排名从击败5%上升到击败70%!!!
java数据结构:堆,PriorityQueue小顶堆,大顶堆翻转(亲手实战)_第1张图片

class KthLargest {
    //小顶堆

    PriorityQueue pq;
    int k;
    public KthLargest(int k, int[] nums) {
        this.k = k;
        pq = new PriorityQueue<>(k);
        for (int i=0; i pq.peek()) {
                pq.poll();
                pq.add(val);
            } 
        }
        return pq.peek();
    }
}
/**
class KthLargest_Backup {
    //这个版本的很慢,beats 6%,因为每次都排序了,所以要试试小顶堆

    List list = new ArrayList<>();
    int k;
    public KthLargest(int k, int[] nums) {
        this.k = k;
        for (int i=0; i list.get(i)) pos++;
            else break;
        }     
        list.add(pos, val);

        //for (int i=0; i

PriorityQueue天生是小顶堆,那么如果我要大顶堆怎么办?

// 默认实现了一个最小堆。 
Queue priorityQueue = new PriorityQueue<>(); 
// 实现最大堆 
Queue priorityQueue = new PriorityQueue(
    lists.size(),
    new Comparator(){ 
        @Override 
        public int compare(ListNode o1, ListNode o2) { return o1.val-o2.val; } 
    }
); 

手动翻转大顶堆

package com.zzz.life;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@SpringBootApplication
public class LifeApplication {
    public static void main(String[] args) {
        //SpringApplication.run(LifeApplication.class, args);
        System.out.println("begin...");
        Node root = new Node(1);
        root.left = new Node(3);
        root.right = new Node(4);
        root.left.left = new Node(5);
        root.left.right = new Node(7);
        root.right.left = new Node(2);
        root.right.right = new Node(6);
        root.left.left.left = new Node(8);
        root.left.left.right = new Node(0);
        LifeApplication app = new LifeApplication();
        List traversal = app.postorderTranversal(root);
        for (Integer item: traversal) {
            System.out.print(item+" ");
        }
        System.out.println("遍历完成");
        List> level = app.levelOrder(root);
        for (List item: level) {
            System.out.println(item);
        }
        List trunk = app.trunkNodes(root);
        for (Node item: trunk) {
            System.out.print(item.val + " : ");
        }
        System.out.println("最终----------");
        app.shiftDD(root);
        List> level2 = app.levelOrder(root);
        for (List item: level2) {
            System.out.println(item);
        }
    }
    public void shiftDD(Node root) {
        //将这个完全二叉树变为大顶堆
        if (root == null) return ;
        //找到这树中最后一个非叶子节点
        List ret = trunkNodes(root);
        for (int i=0; i< ret.size(); i++) {
            Node tmp = ret.get(i);
            int cur = tmp.val;
            int left = tmp.left!=null? tmp.left.val:-1;
            int right = tmp.right!=null? tmp.right.val:-1;
            int maxchild = left > right? left: right;
            //执行交换
            if (maxchild > cur) {
                if (maxchild == left) {
                    tmp.val ^= tmp.left.val;
                    tmp.left.val ^= tmp.val;
                    tmp.val ^= tmp.left.val;
                } else {
                    tmp.val ^= tmp.right.val;
                    tmp.right.val ^= tmp.val;
                    tmp.val ^= tmp.right.val;
                }
            }
            //整理子树
            shiftDD(tmp.left);
            shiftDD(tmp.right);
        }
    }
    public List preorderTranversal(Node root) {
        List list = new ArrayList<>();
        if (root == null) return list;
        list.add(root.val);
        list.addAll(preorderTranversal(root.left));
        list.addAll(preorderTranversal(root.right));
        return list;
    }
    public List postorderTranversal(Node root) {
        List list = new ArrayList<>();
        if (root == null) return list;
        list.addAll(postorderTranversal(root.left));
        list.addAll(postorderTranversal(root.right));
        list.add(root.val);
        return list;
    }
    public List trunkNodes(Node root) {
        List list = new ArrayList<>();
        if (root == null) return list;
        LinkedList current = new LinkedList<>();
        current.add(root);
        boolean hasNext = true;
        while (hasNext) {
            int size = current.size();
            for (int i=0; i> levelOrder(Node root) {
        List> lists = new ArrayList>();
        boolean hasNext = false;
        if (root != null) hasNext =true;
        LinkedList current = new LinkedList<>();
        current.add(root);
        while (hasNext) {
            int size = current.size();
            List list = new ArrayList<>();
            for (int i=0; i

你可能感兴趣的:(Java,数据结构,java,PriorityQueue,小顶堆,大顶堆)