数据结构排序算法之内部排序

树型排序

在这里插入图片描述
原本的待排序列为第1层,然后两两分组,接着从分组中间找出每一个分组中的较小的值,得到第2层,接着从第二层再分组,再找最小值,依次类推,直到整个待排序列中的最小值得出只有应该的时候,停止比较。

现在开始应该考虑输出过程了:

将所有的含有13的结点全部变为无穷大符号,
在这里插入图片描述
接着继续比较,27小于无穷大,所以27选出,27又小于38,所以27变为根节点,也就是整棵树当前的最小值。
在这里插入图片描述
如此排序下去,也可以完成排序操作。

堆排序

堆的数组表示方法

堆是一棵完全二叉树,其中每个结点的关键字都大于其孩子结点的关键字。

大顶堆:所有子树中的根结点的值都大于下面的所有子节点。用于升序排序。

小顶堆:所有子树中的根节点的值都小于下面的所有子节点。用于降序排序。

在这里插入图片描述

所以,每个结点的左孩子都是当前结点的下标的二倍,右孩子是当前结点下标的2被+1。

因此,引出了其数组表达方式:

在这里插入图片描述
数组中存储二叉树结点的次序是根、左、右。

Java实现代码

package com.xingyun.paixu;

import java.util.Arrays;

public class HeapSort {
	/*
	 * 	堆排序
	 * 
	 * */
	public static void main(String[] args) {
		int[] arr = new int[] {9,6,8,7,0,1,10,4,2};
		
/*		
		//每一次都是从最后一个非叶子 结点开始比较的。
		int start=(arr.length-1)/2;
		//每一次都是与第一个元素,也就是根节点进行交换的,所以不需要比较循环到0;
		for(int i=start;i>=0;i--) {
			MaxHeap(arr, arr.length, i);
		}
*/		HeapSort(arr);
		
		System.out.println(Arrays.toString(arr));
	}
	
	//2、开始排序
	public static void HeapSort(int[] arr) {
		//每一次都是从最后一个非叶子 结点开始比较的。
		int start=(arr.length-1)/2;
		//调整为大顶堆
		for(int i=start;i>=0;i--) {
			MaxHeap(arr, arr.length, i);
		}
		//交换位置。将从最后一个开始与第一个元素交换,因为每一次都是与第一个元素进行交换,所以不需要遍历到0
		//将数组中的第0个和堆中的最后一个进行交换,然后再把前面的进行大顶堆构建
		for(int i=arr.length-1;i>0;i--) {
			int temp=arr[i];
			arr[i]=arr[0];
			arr[0]=temp;
			MaxHeap(arr, i, 0);
		}
		
	}
	
	//1、将数组转为大顶堆
	public static void MaxHeap(int[] arr,int size,int index) {
		//左子节点
		int leftNode=2*index+1;
		//右子结点
		int rightNode=2*index+2;
		//先暂定当前结点为最大值
		int max=index;
		//注意这里需要判断左右子结点是否存在,不加判断的话会发生数组下标越界的错误
		//然后比较当前结点和左右两个子节点的值的大小,从这三个结点当中取出应该最大的结点值最为这三个结点的跟结点
		if(leftNode<size&&arr[max]<arr[leftNode]) {
			max=leftNode;
		}
		if(rightNode<size&&arr[max]<arr[rightNode]) {
			max=rightNode;
		}
		
		//如果发生交换行为,需要判断交换位置后的子结点是否满足大顶堆条件,是否大于它的所有子节点
		if(max!=index) {
			int temp=arr[index];
			arr[index]=arr[max];
			arr[max]=temp;
			MaxHeap(arr, size, max);
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值