zoukankan      html  css  js  c++  java
  • 堆(插入删除)

    用堆实现优先级队列,插入和删除都很快o(logN)
    编程语言中的内存堆与这里的数据结构是不一样的
    堆:一种树(特殊的二叉树)
    特点:它是完全二叉树,除了树的最后一层节点不需要是满,其他的每一层从左到右都完全是满的。
    它常常是用一个数组实现
    堆中的每一个节点都满足堆的条件,父节点的关键字要大于所有子节点。
    堆是弱序(遍历不适合)
    插入:获取一个节点,放入完全二叉树中。与其父节点作比较,替换(完成父节点的关键字要大于子节点)
    删除:删除顶端节点,将最后一个叶子节点赋值为顶点节点。然后移动 完成父节点的关键字要大于子节点。
    改变节点优先级:将该节点的值更换。然后将它放在合适的位置(完成父节点的关键字要大于子节点)
    (父节点的关键字要大于所有子节点,即三个点之间选取最大的与临时父节点替换)

    public class Node {
        private int iData;//既是关键字,又是数值
        public Node(int key) {//初始化
            iData=key;
            
        }
        public int getKey() {//访问关键字
            return iData;
        }
        public void setKey(int id) {//改变关键字
            iData=id;
        }
    
    }
    //建立堆
    public class Heap {
        private Node[] heapArray;//存储节点的数组
        private int maxSize;//总大小
        private int currentSize;//当前堆的大小
        public Heap(int mx) {
            maxSize=mx;//初始化总大小
            currentSize=0;//初始化当前数据大小0
            heapArray=new Node[maxSize];
        }
        //判断是否为空
        public boolean isEmpty() {
            return currentSize==0;
        }
        //增加(判断为满,则不能新增)    
        public boolean insert(int key) {
            if(currentSize==maxSize)
                return false;
            Node newNode=new Node(key);//建立key节点
            heapArray[currentSize]=newNode;//将key节点插入数组的最末
            //(向上调整)完成堆的规则(父节点大于子节点)
            trickleUP(currentSize);
            currentSize++;//增加成功,数量加1
            return true;
        }
        //向上调整(只需要跟父节点做比较就行了,因为开始的时候父节点就是最大值)
        public void trickleUP(int index) {
            //取父节点
            int parent=(index-1)/2;
            //比较,交换
            Node bottom=heapArray[index];
            while(index>0 && heapArray[parent].getKey()<bottom.getKey())
            {//寻找需要替换的位置
                heapArray[index]=heapArray[parent];
                index=parent;
                parent=(parent-1)/2;
                
            }
            heapArray[index]=bottom;
        }
        //删除(删除根,将最后一个数据项移到根上,然后做调整)
        public Node remove() {
            Node root=heapArray[0];
            heapArray[0]=heapArray[--currentSize];//将最后一个数据项移到根上
            //向下调整
            trickleDown(0);
            return root;
            
            
        }
        //向下调整
        public void trickleDown(int index) {
            int largeChild;//记录大的子节点
            Node top=heapArray[index];
            while(index<currentSize/2) {//指针到了最后一层才停止循环
                int leftChild=2*index+1;//左子节点
                int rightChile=leftChild+1;    //右子节点
                if(rightChile<currentSize && heapArray[leftChild].getKey()<heapArray[rightChile].getKey())//有右子节点
                    largeChild=rightChile;
                else
                    largeChild=leftChild;
                if(top.getKey()>=heapArray[largeChild].getKey())
                    break;
                heapArray[index]=heapArray[largeChild];//将大的关键字调整
                index=largeChild;
                
            }
            //最后定位Node top=heapArray[index]
            heapArray[index]=top;
            
        }
        //更改关键字
        public boolean change(int index, int newValue) {
            if(index<0 || index >=currentSize)
                return false;//非正常索引
            int oldValue=heapArray[index].getKey();
            heapArray[index].setKey(newValue);//改变数据项
            //如果新的数据项大于旧的数据项,就向上调整。如果小于旧的数据项,就向下调整
            if(oldValue<newValue) {
                trickleUP(index);
            }else
                trickleDown(index);
            return true;
            
        }
        //显示堆
        public void displayHeap() {
            //以数组的方式
            System.out.println("堆数组");
            for(int m=0;m<currentSize;m++)
                if(heapArray[m]!=null)
                    System.out.print(heapArray[m].getKey()+" ");
                else
                    System.out.print("-- ");
            System.out.println();
            //以树状的形式
            int nBlanks=32;//控制空格
            int itemsPerRow=1;//当前层的个数
            int column=0;//当前层的数量
            int j=0;
            String dots="...............................";
            System.out.println(dots+dots);
            while(currentSize>0) {
                if(column==0) {
                    for(int k=0;k<nBlanks;k++)
                        System.out.print(' ');
                }
                System.out.print(heapArray[j].getKey());
                if(++j==currentSize)//全部打印完成
                    break;
                if(++column==itemsPerRow) {//当前层打印完
                    nBlanks/=2;
                    itemsPerRow*=2;
                    column=0;
                    System.out.println();
                }else
                    for(int k=0;k<nBlanks*2-2;k++)
                        System.out.print(' ');
                    
            }
            
            System.out.println("
    "+dots+dots);
            
        }
        
        
    
    }
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Test {
        public static void main(String[] agrs) throws IOException{
            int value,value2;
            Heap theHeap =new Heap(31);
            boolean success;
            theHeap.insert(70);
            theHeap.insert(40);
            theHeap.insert(50);
            theHeap.insert(20);
            theHeap.insert(60);
            theHeap.insert(100);
            theHeap.insert(80);
            theHeap.insert(30);
            theHeap.insert(10);
            theHeap.insert(90);
            while(true) {
                System.out.println("Enter first letter of show ,insert,remove,change:");
                int choice=getChar();
                switch(choice){
                    case 's':
                        theHeap.displayHeap();
                        break;
                    case 'i':
                        System.out.print("enter value");
                        value=getInt();
                        success=theHeap.insert(value);
                        if(!success)
                            System.out.println("man le");
                        break;
                    case 'r':
                        if(!theHeap.isEmpty())
                            theHeap.remove();
                        else
                            System.out.println("不能删除");
                        break;
                    case 'c':
                        System.out.println("输入要改变的索引");
                        value=getInt();
                        System.out.println("输入要改变的值");
                        value2=getInt();
                        success=theHeap.change(value, value2);
                        if(!success)
                            System.out.println("无效的索引");
                        break;
                    default :
                            System.out.println("无效的输入");
                        
                }
                        
            }
            
        }
        public static String getString() throws IOException{
            InputStreamReader isr=new InputStreamReader(System.in);
            BufferedReader br=new BufferedReader(isr);
            return br.readLine();
        }
        public static char getChar() throws IOException{
            return getString().charAt(0);
        }
        public static int getInt() throws IOException{
            return Integer.parseInt(getString());
        }
    
    }
  • 相关阅读:
    Vue 2.x windows环境下安装
    VSCODE官网下载缓慢或下载失败 解决办法
    angular cli 降级
    Win10 VS2019 设置 以管理员身份运行
    XSHELL 连接 阿里云ECS实例
    Chrome浏览器跨域设置
    DBeaver 执行 mysql 多条语句报错
    DBeaver 连接MySql 8.0 报错 Public Key Retrieval is not allowed
    DBeaver 连接MySql 8.0报错 Unable to load authentication plugin 'caching_sha2_password'
    Linux系统分区
  • 原文地址:https://www.cnblogs.com/S-Mustard/p/7710705.html
Copyright © 2011-2022 走看看