堆排序

1. 堆是一种完全二叉树 但是与普通的完全二叉树不同 特点:

  ① 最大堆:父结点的键值比左右孩子的键值大

   ② 对于堆中任意一个节点开始 其子堆还是完全的二叉堆


2. 要点:

    ① 根据 给定的初始数组 建立一个初始堆(从最后一个非叶子结点(数组中索引N/2位置)的值上滤进行调整) 调整的方式 每一次从其左孩子、右孩子和父节点 选择最大的值进行交换 当对堆进行调整形成初始堆。

    ②接下来开始进行堆得排序 排序过程:将堆顶元素与堆最后一个元素进行交换 输出最后一个元素最后调整堆相当于对堆得删除操作。

总结:堆排序 第一步建立初始堆 第二步进行堆顶与堆未元素进行交换 交换之后进行堆得调整,调整策略一样采用向下过滤方式。

package com.offerr;

import java.util.ArrayList;

public class HeapSort<AnyType> {
	
	@SuppressWarnings("rawtypes")
	public static <AnyType extends Comparable<? super AnyType>> ArrayList  heapSort(AnyType [] a)
	{
		ArrayList<AnyType> array=new ArrayList<AnyType>();
		/*buildHeap*/
		for(int i=a.length/2-1;i>=0;i--)
			percDown(a,i,a.length);
		/*heapSort 调换堆首末元素 最后在重新调整堆 */
		for(int i=a.length-1;i>=0;i--)
		{
			swap(a,0,i);
			array.add(a[i]);
			percDown(a, 0, i);
		
		}
		for(int i=0;i<array.size();i++)
			System.out.println(array.get(i)+" ");
		
		return array;
	}

	private static <AnyType> void swap(AnyType[] a, int i, int i2) {
		
		AnyType tmp=a[i];
		a[i]=a[i2];
		a[i2]=tmp;
	}

	private static <AnyType extends Comparable<? super AnyType>> void percDown(AnyType[] a, int i, int length) {
		int child=leftChild(i);
		AnyType tmp;
		
		/*
		 * 从 左 右 父 挑选最大值 进行交换*/
		for(tmp=a[i];leftChild(i)<length;i=child)
		{
			child=leftChild(i);
			if(child!=length-1 && a[child].compareTo(a[child+1])<0)
				child++;
			if(tmp.compareTo(a[child])<0)
				a[i]=a[child];
			else
				break;
		}
		a[i]=tmp;
	}

	private static int leftChild(int i)
	{
		return  2*i+1;
	}
	
	public static void main(String[] args)
	{
		Integer[] array={5,11,7,2,3,17};
		heapSort(array);
	}
}


最后添加一下,其他排序算法:

package com.offerr;

public class EightSort {

	
	public static void MergeSort(int a[],int first,int last,int temp[])
	{
		if(first<last)
		{
			int mid=(first+last)/2;
			
			MergeSort(a, first, mid, temp);
			
			MergeSort(a, mid+1, last, temp);
			
			// 分解成 基本单序列 进行合并
			Merge(a,first,mid,last,temp);
		}
	}

	private static void Merge(int[] a, int first, int mid, int last, int[] temp) {
		
		int i=first,j=mid+1;
		int m=mid,n=last;
		int k=0;
		
		while(i<=m && j<=n)
		{
			if(a[i]<=a[j])
				temp[k++]=a[i++];
			else
				temp[k++]=a[j++];
		}
		
		while(i<=m)
			temp[k++]=a[i++];
		while(j<=n)
			temp[k++]=a[j++];
		
		//回复给原矩阵中
		for(i=0;i<k;i++)
			a[first+i]=temp[i];
	}
	
	public static void Print(int [] a)
	{
		for(int i=0;i<a.length;i++)
			System.out.print(a[i]+" ");
		System.out.println();
	}
	
	public static void HeapSort(int [] a)
	{
		/**建立一个初始堆*/
		for(int i=a.length/2-1;i>=0;i--)
			perDown(a,i,a.length);
		
		// 删除 
		for(int i=a.length-1;i>0;i--)
		{
			int temp=a[0];a[0]=a[i];a[i]=temp;
			perDown(a, 0, i);
		}
		Print(a);
	}

	private static void perDown(int[] a, int s, int len) {
		
		int child;
		int temp;
		
		for(temp=a[s];(child=2*s+1)<len;s=child)
		{
			child=2*s+1;
			if(child!=len-1 && a[child]>a[child+1])  // 挑选 两者中 最大值 与父结点进行比较 删除最大堆 ,最小堆的话 应该是 其中最小值
				child++;
			if(temp>a[child])// 删除最大堆,抛出 最大值存储在末尾
				a[s]=a[child];                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
		    else			
				break;
		}
		a[s]=temp;
	}
	
	public static void main(String[] args)
	{
		int a[]={81,94,11,96,12,35};
		RadixSort(a, 2);
		Print(a);
		
	}
	
	/**
	 * 基数排序:按照 个,十,百 位 排序,每一个 Pos 都有分配 和收集过程
	 * */
	
	public static void RadixSort(int [] a,int d)
	{
		// array[i][0] 二维数组 记录第 i 行 数据个数 位数相同 在本桶中数个数 array存放每一次位数分配 存放数据
		int [][]array=new int[10][a.length+1];
		
		for(int i=0;i<10;i++)
			array[i][0]=0;
		
		for(int pos=1;pos<=d;pos++)
		{
			// 将 数据按照 个,十,百 进行分配,位数相同 分配到同一个桶中
			for(int i=0;i<a.length;i++)
			{
				int row=getNumInPos(a[i],pos);
				int col=++array[row][0];
				
				array[row][col]=a[i];
			}
			
			// 收集
			for(int row=0,i=0;row<10;row++)
			{	for(int col=1;col<=array[row][0];col++)
					a[i++]=array[row][col];
			
				array[row][0]=0;
			}
		}
	}

	private static int getNumInPos(int n, int pos) {
		int temp=1;
		
		for(int i=0;i<pos-1;i++)
			temp*=10;
		return (n/temp)%10;
	}
}


  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值