我的Java学习-排序算法堆排序学习

排序是数据结构里面的一个重点和难点内容。数据结构的学习,在熟悉了各种矩阵、链表的数据组成和方法的使用之后,接下来的内容里面比较难理解掌握但是实际中应用比较多的,也是面试必考的,就是排序。而排序里面比较难理解的,个人感觉,是堆排序。
堆排序是在直接选择排序后面介绍的排序法,由于堆排序里面采用了二叉树和完全二叉树的结构,理解起来有点难度。
直接选择排序法的java代码是:

public int[] selectSort(int[] data){       //直接选择排序
        int k; 
        int temp;
        for(int i = 0; i < data.length - 1; i ++){
            k = i;   		 //从第k = i个位置开始做选择
            for(int j = i + 1; j < data.length; j ++){   //对于当前位置i后面的所有元素,
                if(data[j] < data[k])               //每次比较都选择其中比较小的
                    k = j;                          //循环结束时k的值是后面队列里面值最小的位置所在
            }
            if(k != i){    //如果k值有变动,说明后面记录里有比较小的值
                temp = data[i];         //与当前值进行位置互换
                data[i] = data[k];
                data[k] = temp;
            }             //这里如果k值没有变化,说明位置所在已经是最小值               
        }
        return data;
    }

直接选择排序算法比较好理解,但是在选择的过程中,有很多比较的结果是浪费了,时间复杂度也是比较高的。堆排序算法是在这个算法思路上的改进,有效的记录了前面比较的结果,节省了时间。
直接选择排序,每次比较的结果都没有有效的方式做保存。堆排序算法,在第一次建堆后,里面的数据大小就有了一定的顺序,在后面再次建堆的时候能够利用前面建堆的部分成果,从而节省了部分时间。
建堆的java代码

public void createHeap(int[] data, int low, int high){    //high的值一般是data.length-1
        if((low < high) && (high < data.length)){    //判断数据的合理性
            int j = 0; 
            int k = 0;
            int tmp = 0;
            for(int i = high/2; i >= low; -- i){      //从1/2high的位置开始前推
                tmp = data[i];
                k = i;
                j = 2 * k + 1;          //j的位置是当前i位置的叶结点所在
                while(j <= high){
                    if((j < high) && (j + 1 <= high)
                            && (data[j] < data[j + 1]) ){  
                            //上面的比较信息里已经选择了值比较大的叶结点
                        ++j;				//查看当前根结点下另一个叶结点
                    }
                    if( tmp < data[j]){    
                    //如果当前根结点数据比较叶结点小,将根结点与叶结点交换
                        data[k] = data[j];
                        k = j;
                        j = 2 * k + 1;    
				//查看交换后的叶结点与其叶结点比较有没有数据大小的问题
				//这个会一直比较到最底层叶结点
                    }else{
                        break;
                    }
                }
                data[k ] = tmp;
            }
        }
    }

这个堆排序算法的核心,就是上面的建堆方法这里是最大堆,在建堆后,每次堆顶的数据必然是所有数据里面最大值,而每个根结点的数据也必然是当前根和叶关系里最大值。这样,每次建堆后,里面的数据都是有一定的大小顺序,后面再次建堆,就能够利用到前次的部分成果,时间较少。
堆排序算法,就是每次取堆顶元素后对剩下的元素建堆。

public int[] heapSort(int[] data){    //堆排序
        int tmp = 0;
        createHeap(data, 0 , data.length - 1);   //对当前数据建堆
        for(int i = data.length - 1; i > 0; -- i){ 
            tmp = data[0];
            data[0] = data[i];
            data[i] = tmp;				 //对堆顶元素和最后一位元素做置换
            createHeap(data, 0, i - 1);  //去掉最大值后对剩下的元素继续建堆
        }
        return data;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值