堆排序java实现

来源:互联网 发布:linux 安装jdk gz 编辑:程序博客网 时间:2024/06/06 08:27

堆的定义:
        n个关键字序列K1,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):(1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n/2)或(ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n/2)),称为小根堆(或大根堆)。k(i)相当于二叉树的非叶子结点,K(2i)则是左子节点,k(2i+1)是右子节点。
        若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
        大根堆和小根堆:根结点(堆顶)的关键字是堆里所有结点关键字中最小者(或最大者)的堆称为小根堆(或大根堆)。注意:①堆中任一子树亦是堆。

堆排序:
        堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。
(1)用大根堆排序的基本思想:
① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。
……
直到无序区只有一个元素为止。

java 代码实现建堆和堆排序如下:

public class HeapSort {    /*建队算法*/    public void Filterheap(int heap[],int root,int upper){        /*heap为待筛选的堆,root为堆的根结点,upper为无序区的上界*/        int child; //指向孩子结点        int item;   //作为过渡变量        int r=root;    //r指向根结点        child=2*root+1;  //初始时为根结点的左孩子        while(child<upper){            /*比较左右孩子的关键字值,并取大者*/            if(child+1<upper && heap[child+1]>heap[child]){                child=child+1;            }            /*若根结点不满足堆的条件,则与孩子交换*/            if(heap[r]<heap[child]){                item=heap[r];                heap[r]=heap[child];                heap[child]=item;                r=child;                child=2*child+1;                            }else break;   //若根满足堆的条件,则不交换,并退出筛选        }    }    public void heapSort(int heap[],int n){        /*heap为待排序序列,n为序列长度*/        int i;        int item;//过渡变量        for(i=(n-1)/2;i>0;i--){  //从第一个非页结点开始创建初始堆            Filterheap(heap,i,n);        }        for(i=n-1;i>0;i--){  //做n-1趟排序,每次堆的大小减1            /*将堆顶元素与当前大根堆的最后一个元素交换*/            item=heap[0];            heap[0]=heap[i];            heap[i]=item;            /*筛选,将0~i的元素重新调整*/            Filterheap(heap,0,i);             /*显示排序过程*/            for(int j=0;j<n;j++){                System.out.print(heap[j]+", ");            }            System.out.println();        }    }    public static void main(String[] args) {        /*使用堆排序法进行排序*/        int heap[]=new int[]{9,8,7,6,5,4,3,2,1};  //把待排序的数存放在数组中        int n=heap.length;        HeapSort hs=new HeapSort();        hs.heapSort(heap,n);    }}
0 0
原创粉丝点击