数据结构复习之–“堆排序”-JAVA实现

堆排序的时间复杂为O(nlogn),且相对于快速排序来说,其最坏情况下时间复杂也为O(nlogn),且其仅仅需要一个记录大小供交换用的辅助存储空间。
堆排序对于记录较少的文件并不值得提倡,但n比较大的文件是效果很好的。

复习用的练习代码,仅供参考,写的不好,勿喷!

import java.util.Scanner;

public class HeapSortTest {

    private int [] dataArray;//成员变量存储待排序数据

    /**
     * function:使一个除根节点不满足堆定义,其它节点都满足堆定义且使用顺序存储结构存储的树  为一个大顶堆
     * 
     * @param start  调整的起点
     * @param end  调整的终点
     */
    private void HeapAdjust(int start, int end) {

      /*第一种方式:根节点与子树中节点大的进行比较,若子节点比根节点大,
        那么子节点向上移动覆盖父节点,此时根节点以及保存了,不用担心覆盖
        不断向子树查找,直到找到一个子节点比根节点小,此时将根节点赋值给
        该子节点的父节点,因为前面的步骤该子节点的父节点作已为上一轮的子
        节点向上移动了,而最开始的根节点已经保存了,故不会造成数据的覆盖丢失
        整个过程相当于从根节点开始,沿着一条最大值的路线向上移动,然后将根节
        点插入到在堆中其应该在的位置,这种做法使得根节点不需要频繁的移动,一次到位*/

        this.dataArray[0] = this.dataArray[start];
        int i = 2 * start;

        //寻找根节点,在堆中应该在的位置,在寻找的过程中,大的子节点不断向上移动到其父节点的位置
        //注意:在寻找的过程中,最后一个节点也应该包含在内,故i<=end

        for (; i <=end; i *= 2) {
            //注意此时的 i<end不能少,因为在判断start的左右子树时,得先确保start有右子树
            if (i<end && this.dataArray[i] < this.dataArray[i + 1])
                i++;
            if (this.dataArray[0]>this.dataArray[i]) break;
            //当根节点小于当前节点时,子节点中大的节点,覆盖父节点        
            this.dataArray[start]=this.dataArray[i];
            start=i;
        }
        this.dataArray[start]=this.dataArray[0];//一步到位,将根节点移动到其在堆中应在的位置


        /*
        //第二种方式:子节点中较大的节点与父节点进行比较,若子节点比父节点大,
        //该方式可能需要频繁的交换,使得时间增加。整个过程相当于根节点沿着最大
        //值路径慢慢的移动到其在堆中应该所处的位置
        //此处i小于等于end的因为最后一个也需要进行判断
        for (int i = 2*start ; i <=end ; i*=2) {

            //注意此处前面的i<end,因为要确保start有右孩子才进行左右孩子的判断
            if (i<end && this.dataArray[i] < this.dataArray[i + 1])
                i++;
            if (this.dataArray[start] >= this.dataArray[i])
                break;
            this.dataArray[0] = this.dataArray[start];
            this.dataArray[start] = this.dataArray[i];
            this.dataArray[i] = this.dataArray[0];
            start = i;
        }
        */
    }

    /**
     * function:进行堆排序
     */
    public void HeapSort(){
        int temp;
        //将数组中的数据建成堆,从最后一个节点的父节点开始(n/2处),往上直到根节点,从而建成一个大根堆
        for (int i = (this.dataArray.length-1)/2; i >0; i--) {
            HeapAdjust(i, this.dataArray.length-1);
        }

        //将根移动到树的最后一个元素,再次调整,使其仍为一个大根堆,不断重复上面的步骤
        for (int i = this.dataArray.length-1; i >1; i--) {
            temp=this.dataArray[1];
            this.dataArray[1]=this.dataArray[i];
            this.dataArray[i]=temp;
            //每次调整,调整的范围都不包括以前从根替换到树最后的节点,因此每次调整
            //的范围会不断缩小,直到只剩下根节点,此时数组中的数据全部排序了
            HeapAdjust(1,i-1);
        }       
    }

    public HeapSortTest() {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入待排序个数:");
        int totalNums = sc.nextInt();
        this.dataArray=new int[totalNums+1];
        System.out.println("请输入待排序数据,以空格分隔:");
        for (int i = 1; i < dataArray.length; i++) {
            this.dataArray[i]=sc.nextInt();
        }
    }

    /**
     * function: 显示成员数组中的数据
     */
    private void show(){
        for (int i = 1; i < dataArray.length; i++) {
            System.out.print(dataArray[i]+" ");
        }
        System.out.print("\n");
    }

    public static void main(String[] args) {
        HeapSortTest hst = new HeapSortTest();
        hst.show();
        hst.HeapSort();
        hst.show();
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值