八十八.二叉树遍历、堆排序(查找与排序(三))——JAVA

查找与排序(一)
查找与排序(二)
查找与排序(四)
二叉树的遍历
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import java.util.Scanner;

public class LianXi {
    
    
	
	//前序遍历
	public static void preOrder(int []arr, int i){
    
    
		if(i >= arr.length)
			return;
		System.out.print(arr[i] + " ");   //输出根节点
		preOrder(arr, 2 * i + 1);    //递归输出左子树
		preOrder(arr, 2 * i + 2);    //递归输出右子树
	}
	
    //中序遍历
	public static void inOrder(int []arr, int i){
    
    
		if(i >= arr.length)
			return;
		inOrder(arr, 2 * i + 1);     //递归输出左子树
		System.out.print(arr[i] + " ");  //输出根节点
		inOrder(arr, 2 * i + 2);     //递归输出右子树
	}
	
	//后序遍历
	public static void postOrder(int []arr, int i){
    
    
		if(i >= arr.length)
			return;
		postOrder(arr, 2 * i + 1);   //递归输出左子树
		postOrder(arr, 2 * i + 2);   //递归输出右子树
		System.out.print(arr[i] + " ");  //输出根节点
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []arr = new int[N];
		for(int i = 0 ; i<N; i++){
    
    
			 arr[i] = in.nextInt();
		}
		System.out.println("初始数组为:");
		for(int i = 0 ; i<N; i++){
    
    
			System.out.print(arr[i] + " ");
		}
		System.out.println("\n");
		System.out.println("前序遍历:");
		preOrder(arr, 0);
		System.out.println("\n");
		System.out.println("中序遍历:");
		inOrder(arr, 0);
		System.out.println("\n");
		System.out.println("后序遍历:");
		postOrder(arr, 0);
	}
}

在这里插入图片描述

堆的概念

  • 二叉堆是完全二叉树或者是近似完全二叉树。
  • 二叉堆满足二个特性:
    1、父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
    2、每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)
  • 任意节点的值都是大于其子节点的值——大顶堆
  • 任意节点的值都是小于其子节点的值——小顶堆

在这里插入图片描述
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

堆排序
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

步骤
1、构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
2、将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

最小堆排序

import java.util.Scanner;

public class LianXi {
    
    
   /*	 
    * MinHeap(A){
    *    n = A.length;
    *    for i from n/2-1 down to 0{
    *        MinHeapFixDown(A,i,n);
    *    }
    * }
    * MinHeapFixDown(A,i,n){
    *  // 找到左右孩子
    *  left = 2 * i + 1;
    *  right = 2 * i + 2;
    *  //左孩子已经越界,i就是叶子节点
    *  if(left>=n){
    *     return; 
    *  }
    *  
    *  min = left;
    *  if(right >= n){
    *     min = left;
    *  }
    *  else{
    *     if(A[right] < A[left])
    *       min = right;
    *  
    * }
    * //min指向了左右孩子中较小的那个
    * //如果A[i]比两个孩子都要小,不用调整
    * if(A[i] <= A[min]){
    *    return ;
    * }
    * // 否则,找到两个孩子中较小的,和i交换
    * swap(A,i,min)
    * //小孩子那个位置的值发生了变化,i变更为小孩子那个位置,递归调整
    * MinHeapFixDown(A,min,n);
    * 
    * sort(A):
    * //先对A进行堆化
    * MinHeap(A);
    * for(int x = n-1; x>=0; x--)
    *    //把堆顶,0号元素和最后一个元素对调
    *    swap(A,0,x);
    *    //缩小堆的范围,对堆顶元素进行向下调整
    *    MinHeapFixDown(A,0,x-1)
   */
	
	public static void MinHeap(int []A){
    
    
		int n = A.length;
		for(int i = n/2-1; i>=0; i--){
    
    
			MinHeapFixDown(A, i, n);
		}
	}  
	
	public static void MinHeapFixDown(int []A, int i, int n){
    
    
		int left = 2 * i + 1;
		int right = 2 * i + 2;
		if(left >= n){
    
    
			return ;
		}
		int min = left;
		if(right >= n){
    
    
			min = left;
		}
		else{
    
    
			if(A[right] < A[left]){
    
    
				min = right;
			}
		}
		if(A[i] <= A[min]){
    
    
			return ;
		}
		swap(A,i,min);
		MinHeapFixDown(A, min, n);
	}
	
	public static void sort(int []A){
    
    
		MinHeap(A);
		for(int x = A.length-1; x>=0; x--){
    
    
			swap(A,0,x);
			MinHeapFixDown(A, 0, x-1);
		}
	}
	public static void swap(int[]A, int i, int min){
    
    
		int temp = A[i];
		A[i] = A[min];
		A[min] = temp;
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []A = new int[N];
		for(int i = 0; i<N; i++){
    
    
			A[i] = in.nextInt();
		}
		System.out.println("初始数组为:");
		for(int i = 0; i<N; i++){
    
    
			System.out.print(A[i]+ " ");
		}
		System.out.println("\n");
		sort(A);
		System.out.println("最小堆排序后数组为:");
		for(int i = 0; i<N; i++){
    
    
			System.out.print(A[i] + " ");
		}
	}
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/JiangYu200015/article/details/113770464