Sorting algorithm----------heap sort

Heap sort

Introduction

Heap sort is also a sort of selection , the worst and best average time complexity is O(nlogn), which is unstable sort

It is a complete binary tree, the value of each node is greater than or equal to the value of its left and right child nodes ===> large push, note that it does not require the size relationship between the left and right child nodes, otherwise it is a small top heap

Basic idea

1. Construct the sequence to be sorted into a large top heap

At this time, the maximum value of the entire sequence is the root node of the heap item.

Exchange it with the last element, and the end is the maximum value at this time.

Then reconstruct the remaining n-1 elements into a pile, so that the next smallest value of n elements will be obtained. Such repeated execution will result in an ordered sequence.

Diagram

img

The example in the instructional video is given an array {4,6,8,5,9} using the heap sort algorithm

Insert picture description here

Then we start from the last non-leaf node (the leaf node naturally does not need to be adjusted, the first non-leaf node arr.length/2-1=5/2-1=1, which is the 6 nodes below), Adjust from left to right and bottom to top .

Insert picture description here

Then find the second non-leaf node 4, find that 9 elements of 4, 9, 8 are the largest, and 4 and 9 are exchanged

Insert picture description here

At this time, the exchange caused the structure of the sub-root [4,5,6] to be chaotic, and continue to adjust. In [4,5,6], 6 is the largest, and 4 and 6 are exchanged.

Insert picture description here

So far, our big push is completed

Step two

Exchange the top element with the last element to make the last element the largest. Then continue to adjust the heap, and
exchange the top element with the last element to get the second largest element. Exchange, rebuild, and exchange are repeated in this way.

Insert picture description here

9 is not used for sorting anymore, we will treat it as moving out of the array

Then readjust the structure to continue to meet the heap definition

Insert picture description here

Then swap the top element 8 with the last element 5 to get the second largest element 8.

Insert picture description here

Subsequent operations repeat the above, and finally get an ordered sequence

Insert picture description here

Teacher's summary

1. Construct the disordered sequence into a pile, and select the large top pile or the small top pile according to the requirements of ascending and descending order;

2. Exchange the top element with the end element [sink the largest element to the end of the array

3. Re-adjust the structure to meet the definition of the heap, and then continue to exchange the top element of the heap with the current end element, and repeat the adjustment + exchange steps until the entire sequence is in order.

Code

package;

import java.util.Arrays;

//堆排序
//2021年1月31日21:26:04
//作者 @王
public class HeapSort {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		int arr[] ={
    
    4,6,8,5,9};
		heapSort(arr);
	}
	
	//编写堆排序的方法
	public static void heapSort(int[] arr){
    
    
		int temp = 0;
		System.out.println("堆排序");
		
//		//分步完成
//		adjustHeap(arr, 1, arr.length);
//		System.out.println("第一次调整"+Arrays.toString(arr));
//		adjustHeap(arr, 0, arr.length);
//		System.out.println("第二次调整"+Arrays.toString(arr));
		//将我们的数组变成一个大顶堆
		for (int i = arr.length/2 -1; i >=0; i--) {
    
    
			adjustHeap(arr, i, arr.length);
		}

		//将堆顶元素与末尾元素交换,将最大元素沉到数组末端
		//重新调整结构,使其满足堆定义,然后继续减缓堆顶元素与当前末尾元素,反复
		//执行调整+交换步骤直到整个序列有序
		for(int j = arr.length-1;j>0;j--){
    
    
			//交换
			temp = arr[j];
			arr[j] = arr[0];
			arr[0] = temp;
			adjustHeap(arr, 0, j);
		}
	}
	//将一个数组(二叉树),调整成一个大顶堆或者小顶堆
	/**
	 * 功能:完成将以i对应的非叶子结点的树调整成大顶堆
	 * 举例  4,6,8,5,9  => i=1   => 得到 4,9,8,5,6
	 * @param arr
	 * @param i		表示非叶子节点在数组中的索引 
	 * @param length	表示对多少个元素继续调整,length是在逐渐的减少
	 */
	public static void adjustHeap(int arr[],int i,int length){
    
    
		int temp = arr[i];//取出当前元素的值,保存在临时变量
		//开始调整
		//1. k = i*2+1   k 是i节点的左子节点
		for (int k = i * 2 +1; k < length; k = k * 2 +1) {
    
    
			if(k + 1 < length && arr[k] < arr[k+1]){
    
    
				//说明左子节点的值小于右子节点的值
				k++;//k指向右子节点
			}
			if(arr[k] > temp){
    
    
				//如果子节点大于父节点
				arr[i] = arr[k];
				i = k;//i指向K  继续循环比较 
			}else{
    
    
				break;
			}
		}
		//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了最顶上(局部)
		arr[i] = temp;
	}

}

Guess you like

Origin blog.csdn.net/qq_22155255/article/details/113823058