zoukankan      html  css  js  c++  java
  • 堆排序之Java实现

    堆排序思想:

    堆排序,顾名思义,就是基于堆。堆分为最大堆和最小堆,事实上就是全然二叉树。最大堆要求节点的元素都要大于其孩子,最小堆要求节点元素都小于其左右孩子,两者对左右孩子的大小关系不做不论什么要求,事实上非常好理解。有了上面的定义,我们能够得知,处于最大堆的根节点的元素一定是这个堆中的最大值。事实上我们的堆排序算法就是抓住了堆的这一特点,每次都取堆顶的元素,将其放在序列最后面,然后将剩余的元素又一次调整为最大堆,依次类推,终于得到排序的序列。
    或者说,堆排序将全部的待排序数据分为两部分,无序区和有序区。无序区也就是前面的最大堆数据,有序区是每次将堆顶元素放到最后排列而成的序列。每一次堆排序过程都是有序区元素个数添加,无序区元素个数降低的过程。当无序区元素个数为1时,堆排序就完毕了。
    本质上讲,堆排序是一种选择排序,每次都选择堆中最大的元素进行排序。仅仅只是堆排序选择元素的方法更为先进,时间复杂度更低,效率更高。

    代码实现例如以下:

    public abstract class HeapSort<E> {
    	public abstract boolean compare(E value1, E value2);//value1小于value2则返回true
    	
    	public boolean heapSort(List<E> list){//排序
    		return heapSort(list, list.size());
    	}
    	
    	public boolean heapSort(List<E> list, int n){
    		if(null == list || 0 == list.size()){
    			return false;
    		}
    		if(!heapCreate(list, n)){
    			return false;
    		}
    		for(int i = n; i > 0; --i){
    			swap(list, 0, i - 1);
    			heapAdjust(list, 0, i - 1);
    		}
    		return true;
    	}
    	
    	public boolean heapCreate(List<E> list, int length){ //创建小根堆
    		if(null == list || 0 == list.size()){
    			return false;
    		}
    		for(int i = (length / 2 - 1); i >= 0; --i){
    			if(!heapAdjust(list, i, length)){
    				return false;
    			}
    		}
    		return true;
    	}
    	
    	public boolean heapAdjust(List<E> list, int middle, int length){//调整堆,使其满足小根堆的条件
    		if(null == list || 0 == list.size()){
    			return false;
    		}
    		E temp = list.get(middle);
    		for(int i = (2 * middle + 1); i < length; i *= 2){
    			if(i < (length - 1) && !this.compare(list.get(i), list.get(i + 1))){
    				++i;
    			}
    			if(this.compare(temp,list.get(i))){
    				break;
    			}
    			list.set(middle, list.get(i));
    			middle = i;
    		}
    		list.set(middle, temp);
    		return true;
    	}
    	
    	public void swap(List<E> list, int i, int j){//数据交换
    		E temp = list.get(i);
    		list.set(i, list.get(j));
    		list.set(j, temp);
    	}
    }

  • 相关阅读:
    angular.element函数
    mknod创建命名管道(I/O缓存)
    谈谈sipXecs及其它【转】
    Linux下判断cpu物理个数、几核
    shell 中判断文件/文件夹是否存在
    一个人可以用Open IMS Core做什么呢
    linux 下更改磁盘名
    PPTP 服务器配置
    IP多媒体子系统[转维基百科]
    针对用编译的方式安装时的卸载
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4332761.html
Copyright © 2011-2022 走看看