堆(利用堆进行数组排序)-堆排序

Posted S-Mustard

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆(利用堆进行数组排序)-堆排序相关的知识,希望对你有一定的参考价值。

将随意填充的数组排序成堆的形式,然后进行删除堆的操作,因为堆删除的永远是当前堆中最大的,根据这个特性,可以获取有序的数组
(排成堆)从最后一个父节点开始向下调整,一直到最上面的父节点。
(删除堆)删除操作,获得的是当前最大的值

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 void insertAt(int index,Node newNode) {
        heapArray[index]=newNode;
    }
    //给当前数据项值加1
    public void incrementSize() {
        currentSize++;
    }
    //删除一个数据
    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];
            //找到top的位置
            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 isEmpty() {
        return currentSize==0;
    }
    //显示堆
        public void displayHeap() {
            //以树状的形式
            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("\n"+dots+dots);
            
        }
        public void displayArray() {
            for(int m=0;m<maxSize;m++)
                
                    System.out.print(heapArray[m].getKey()+" ");
                
            System.out.println();
        }
    
    
    

}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] agrs) throws IOException{
        int size,j;
        System.out.println("enter number of items:");
        size=getInt();
        Heap theHeap =new Heap(size);
        for(j=0;j<size;j++) {//将随机数放入先存入堆的数组中
            int random=(int)(java.lang.Math.random()*100);
            Node newNode=new Node(random); 
            theHeap.insertAt(j, newNode);
            theHeap.incrementSize();
        }
        //显示
        theHeap.displayHeap();
        //排序堆(将一个填充的数组变成堆的形式,然后排序)
        //从最后一个父节点开始调整,一直到根
        for(j=size/2-1;j>=0;j--) {
            theHeap.trickleDown(j);
        }
        System.out.print("heap:");
        theHeap.displayHeap();
        //排序
        for(j=size-1;j>=0;j--) {
            Node biggestNode=theHeap.remove();//取出最大的数据项
            theHeap.insertAt(j, biggestNode);//放入堆的底层数组的倒数节点中
        }
        System.out.println("排序后数组:");
        theHeap.displayArray();
        
        
    
                    
        
        
    }
    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());
    }

}

 

以上是关于堆(利用堆进行数组排序)-堆排序的主要内容,如果未能解决你的问题,请参考以下文章

算法排序之堆排序

基础排序算法四——堆排序

算堆排序

重温基础算法内部排序之堆排序法

重温基础算法内部排序之堆排序法

堆排序