选择类排序——简单排序和堆排序

参考:

https://download.csdn.net/download/qq_31567335/10356263

什么是堆?

堆是一颗完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。而且堆还必须满足以下性质:父节点大于等于左右子节点(大堆),或者父节点小于等于左右子节点(小堆),后面为了表述方便,在文章中只讨论大堆。

由此可以看出大堆有二个重要的性质:

1.在堆顶的一定是值最大的元素。

2.堆的左右子树还是一个堆。

用什么样的数据结构存储堆?

表示方式出乎想象的简单。由此图:

观察可以发现:i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。

所以说,只需要将堆按从上到下,从左到右的顺序存储在数组中即可。用上面总结出的公式寻找某个节点的父节点或者子节点。

怎么由原始数组构造出堆?

按从右到左,从下到上的顺序对每个节点进行判断。确保此节点大于其左右子节点。如果不满足,就找出左右子节点中最大的,进行交换。当然,交换完成后,子节点可能不再满足堆的性质,所以需要进行递归,直到到达叶子结点。由于最后一个元素的父节点坐标是(n – 1) / 2,大于这个节点的都是叶子节点。所以只需要从(n – 1) / 2开始判断即可。

时间复杂度:n*lgn。(用极限貌似可以算出来是n,nlgn可以认为是一个粗略但是正确的结果)

怎么利用堆进行排序?

构造出堆之后,将第一个元素(最大的元素)和数组最后一个元素进行交换,同时将堆的规模减小1。

对第一个元素进行一次维护,时间复杂度为lgn。

重复此步骤,直到每个元素都完成排序。

总时间复杂度为nlgn。

 代码实现:

package dataStructureAndAlgorithms;

public class SelectSort {
	
	//简单选择排序
	public static void simpleSelectSort(int[] array){
		int length = array.length;
		//最小值的下标
		int minIndex = 0;
		//选出第i个位置上的元素。位置0上是最小的,1上是第二小的...最后一个位置上的元素不用选择
		for(int i=0;i<length-1;i++){
			minIndex = i;
			for(int j=i+1;j<length;j++){
				if(array[j]<array[minIndex]){
					minIndex = j;
				}
			}
			if(minIndex != i){
				int temp = array[minIndex];
				array[minIndex] = array[i];
				array[i] = temp;
			}
			System.out.println("经过第"+ (i+1) + "轮排序后:");
			display(array);
		}
	}
	
	//堆排序
	public static void heapSort(int[] array){
		int maxIndex = array.length - 1;
		//构造堆
		for(int index = (maxIndex-1)/2;index>=0;index-- ){
			maxHeap(array, index, maxIndex);
		}
		
		System.out.println("构造完成的堆:");
		display(array);
		
		
		int count = 0;
		//排序
		for(int i=maxIndex;i>=1;i--){
			int temp = array[i];
			array[i] = array[0];
			array[0] = temp;
			maxHeap(array, 0, i-1);
			
			System.out.println("经过第"+ (count++) + "轮排序后:");
			display(array);
		}
	}

	/**
	 * 
	 * @param array
	 * @param index   需要维护堆性质的结点
	 * @param size   堆的大小
	 */
	public static void maxHeap(int[] array,int index,int maxIndex){
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int largest = index;
		if(left <= maxIndex && array[largest] < array[left]){
			largest = left;
		}
		if(right <= maxIndex && array[largest] < array[right]){
			largest = right;
		}
		
		if(largest != index){
			int temp = array[index];
			array[index] = array[largest];
			array[largest] = temp;
			maxHeap(array, largest, maxIndex);
		}
	}
	
	public static void display(int[] array){
		for(int i=0;i<array.length;i++){
			System.out.print(array[i] + " ");
		}
		System.out.println();
	}
	
	public static void main(String args[]){
		int[] originArray = {4,2,8,9,5,7,6,1,3};
		int[] array = new int[originArray.length];

        System.arraycopy(originArray, 0, array, 0, originArray.length);
        System.out.println("\n\n未排序数组顺序为:");
        display(array);
        System.out.println("-----------------------");
        simpleSelectSort(array);
        System.out.println("-----------------------");
        System.out.println("经过选择排序后的数组顺序为:");
        display(array);
	        
	        
        System.arraycopy(originArray, 0, array, 0, originArray.length);
        System.out.println("\n\n未排序数组顺序为:");
        display(array);
        System.out.println("-----------------------");
        heapSort(array);
        System.out.println("-----------------------");
        System.out.println("经过大堆排序后的数组顺序为:");
        display(array);    
	        
	}
}

输出结果:

未排序数组顺序为:
4 2 8 9 5 7 6 1 3 
-----------------------
经过第1轮排序后:
1 2 8 9 5 7 6 4 3 
经过第2轮排序后:
1 2 8 9 5 7 6 4 3 
经过第3轮排序后:
1 2 3 9 5 7 6 4 8 
经过第4轮排序后:
1 2 3 4 5 7 6 9 8 
经过第5轮排序后:
1 2 3 4 5 7 6 9 8 
经过第6轮排序后:
1 2 3 4 5 6 7 9 8 
经过第7轮排序后:
1 2 3 4 5 6 7 9 8 
经过第8轮排序后:
1 2 3 4 5 6 7 8 9 
-----------------------
经过选择排序后的数组顺序为:
1 2 3 4 5 6 7 8 9 


未排序数组顺序为:
4 2 8 9 5 7 6 1 3 
-----------------------
构造完成的堆:
9 5 8 3 4 7 6 1 2 
经过第0轮排序后:
8 5 7 3 4 2 6 1 9 
经过第1轮排序后:
7 5 6 3 4 2 1 8 9 
经过第2轮排序后:
6 5 2 3 4 1 7 8 9 
经过第3轮排序后:
5 4 2 3 1 6 7 8 9 
经过第4轮排序后:
4 3 2 1 5 6 7 8 9 
经过第5轮排序后:
3 1 2 4 5 6 7 8 9 
经过第6轮排序后:
2 1 3 4 5 6 7 8 9 
经过第7轮排序后:
1 2 3 4 5 6 7 8 9 
-----------------------
经过大堆排序后的数组顺序为:
1 2 3 4 5 6 7 8 9 

猜你喜欢

转载自blog.csdn.net/qq_31567335/article/details/79890158