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;
}
}