优先队列的出队操作

12 篇文章 0 订阅
4 篇文章 0 订阅

要点:

  • 了解 shiftDown
  • 了解优先队列 出队的机制
    上一篇文章中我写了优先队列的入队操作,入队shiftUp,出队shiftDown
    看代码效果:

在这里插入图片描述
首先,在优先队列插入50个元素,执行poll操作,也就是出队
把队顶的一个元素拿出
在这里插入图片描述
如图,2个97只剩下一个

对于一个50个元素的大根堆,只要出队,就变成49个元素,这里我使用 count–,因此数组长度并不是真的变成了49个,而是模拟 了一个出队,第50个元素还是存在的,这个大根堆的容量只有100个
当大根堆满了之后,要重新创建一个数组,维护一个新的大根堆,这个功能我就暂时先不实现了

出队主要是把队首和队尾的元素交换,然后执行shiftDown 操作,也就是和他的儿子,比较,如果父亲比儿子小,儿子上来,父亲下去,重复这个操作,你就又维持了一个大根堆,具体可以看我的上一篇文章, 优先队列的入队操作

package day1;


import util.AlgoVisHelper;
import util.AlgoVisualizer;

import java.util.*;

/**
 * Created by ASUS on 2019/8/22.
 */
public class Main {


    public static void main(String[] args) {


        Random r = new Random();
        MaxHeap  p = new MaxHeap(100);
        int n = 50;
        int m =100;
        for(int i=0;i<n;++i) {
            int t = r.nextInt(100);
            p.insert(t);

        }


        p.treePrint();
        System.err.println("----------------------------------------------------------------");
        int big = p.poll();
        System.err.println("------  big  " +big   + " -----------------------");
        p.treePrint();


    }





}





class MaxHeap {
    int[] data;
    int count;
    int capacity;

    public MaxHeap(int capacity) {
        this.capacity = capacity;
        data = new int[capacity];
        this.count=0;

    }
    int size() {
        return count;
    }

    public boolean isEmpty() {
        return count==0;
    }
    void insert(int e) {
        data[count+1]=e;
        count++;
        shiftUp(count);
    }

    void swap(int i,int j) {
        if(data[i]==data[j])return;
        data[i]^=data[j];
        data[j]^=data[i];
        data[i]^=data[j];
    }

    void shiftUp(int k) {
        while (k>1&&data[k]>data[k/2])
        {
            swap(k,k/2);
            k/=2;
        }
    }
	 int poll() {
	        if(count<0)return 0;
	        int ret = data[1];
	        swap(1,count);
	        count--;
	        shiftDown(1);
	        return ret;
	    }

    void shiftDown(int k) {
        while (2*k<=count) {
            int j = 2*k;
            if(j+1<=count&&data[j+1]>data[j]) {//尽量和大的交换
                j+=1;
            }
            if(data[k]>=data[j]) {
                break;
            }
            swap(k,j);
            k=j;
        }
    }




    public void treePrint() {

        // 最多打印100个元素
        if (size() >= 100) {
            System.out.println("This print function can only work for less than 100 integer");
            return;
        }

        System.out.println("The max heap size is: " + size());
        System.out.println("Data in the max heap: ");
        for (int i = 0; i < size(); i++) {
            // 我们的print函数要求堆中的所有整数在[0, 100]的范围内
            assert (Integer) data[i] >= 0 && (Integer) data[i] < 100;
            System.out.println(data[i] + " ");
        }

        System.out.println();
        System.out.println();

        int n = size();
        int maxLevel = 0;
        int numberPerLevel = 1;
        while (n > 0) {
            maxLevel += 1;
            n -= numberPerLevel;
            numberPerLevel *= 2;
        }

        int maxLevelNumber = (int) Math.pow(2, maxLevel - 1);
        int curTreeMaxLevelNumber = maxLevelNumber;
        int index = 1;
        for (int level = 0; level < maxLevel; level++) {

            String line1 = new String(new char[maxLevelNumber * 3 - 1]).replace('\0', ' ');

            int curLevelNumber = Math.min(count - (int) Math.pow(2, level) + 1, (int) Math.pow(2, level));
            boolean isLeft = true;
            for (int indexCurLevel = 0; indexCurLevel < curLevelNumber; index++, indexCurLevel++) {
                line1 = putNumberInLine((Integer) data[index], line1, indexCurLevel, curTreeMaxLevelNumber * 3 - 1, isLeft);
                isLeft = !isLeft;
            }
            System.out.println(line1);

            if (level == maxLevel - 1) {
                break;
            }

            String line2 = new String(new char[maxLevelNumber * 3 - 1]).replace('\0', ' ');
            for (int indexCurLevel = 0; indexCurLevel < curLevelNumber; indexCurLevel++) {
                line2 = putBranchInLine(line2, indexCurLevel, curTreeMaxLevelNumber * 3 - 1);
            }
            System.out.println(line2);

            curTreeMaxLevelNumber /= 2;
        }
    }


    private String putNumberInLine(Integer num, String line, int indexCurLevel, int curTreeWidth, boolean isLeft) {

        int subTreeWidth = (curTreeWidth - 1) / 2;
        int offset = indexCurLevel * (curTreeWidth + 1) + subTreeWidth;
        assert offset + 1 < line.length();
        if (num >= 10) {
            line = line.substring(0, offset + 0) + num.toString()
                    + line.substring(offset + 2);
        } else {
            if (isLeft) {
                line = line.substring(0, offset + 0) + num.toString()
                        + line.substring(offset + 1);
            } else {
                line = line.substring(0, offset + 1) + num.toString()
                        + line.substring(offset + 2);
            }
        }
        return line;
    }

    private String putBranchInLine(String line, int indexCurLevel, int curTreeWidth) {

        int subTreeWidth = (curTreeWidth - 1) / 2;
        int subSubTreeWidth = (subTreeWidth - 1) / 2;
        int offsetLeft = indexCurLevel * (curTreeWidth + 1) + subSubTreeWidth;
        assert offsetLeft + 1 < line.length();
        int offsetRight = indexCurLevel * (curTreeWidth + 1) + subTreeWidth + 1 + subSubTreeWidth;
        assert offsetRight < line.length();

        line = line.substring(0, offsetLeft + 1) + "/" + line.substring(offsetLeft + 2);
        line = line.substring(0, offsetRight) + "\\" + line.substring(offsetRight + 1);

        return line;
    }
}


















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值