百度解释:堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
大顶堆
public class HeapSort {
public static void adjustMaxHeap(int[] array,int lastindex){
for (int i = (lastindex-1)/2; i>=0 ; i--) {
int k=i;
while(k*2+1<=lastindex){
int biggerindex=k*2+1;
if(biggerindex<lastindex){//防止溢出
if(array[biggerindex]<array[biggerindex+1]){
biggerindex++;
}
}
if(array[k]<array[biggerindex]){
swap(array,k,biggerindex);
k=biggerindex;
}else{
break;
}
}
}
}
public static void heapSort(int[] array){
for (int i = 0; i <array.length-1 ; i++) {
adjustMaxHeap(array,array.length-1-i);
swap(array,0,array.length-1-i);
}
}
public static void swap(int[] array,int i,int j){
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
public static void main(String[] args) {
int[] array={1,7,8,9,6};
heapSort(array);
for(int a:array){
System.out.println(a);
}
}
}
小顶堆
public class HeapSort2 {
public static void adjustMinHeap(int[] array,int lastindex){
//i初始值为最后一个非子节点的索引
for (int i = (lastindex-1)/2; i>=0 ; i--) {
int k=i;
while(2*k+1<=lastindex){
int smallerindex=k*2+1;
if(smallerindex<lastindex){
if(array[smallerindex]>array[smallerindex+1]){//左孩子值大于有孩子则交换
smallerindex++;
}
}
if(array[k]>array[smallerindex]){//最小子节点的值小于父节点的值则交换
swap(array,k,smallerindex);
k=smallerindex;
}else{
break;
}
}
}
}
public static void heapSort(int[] array){
for (int i = 0; i <array.length ; i++) {
adjustMinHeap(array,array.length-1-i);
swap(array,0,array.length-1-i);
}
}
public static void swap(int[] array,int i,int j){
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
public static void main(String[] args) {
int[] array={1,7,8,9,6};
heapSort(array);
for(int a:array){
System.out.println(a);
}
}
}
双堆求中位数:
算法描述:
1、创建两个堆(一个小顶堆、一个大顶堆),堆大小至少为给定数据个数的一半,向上取整;
2、假定变量mid用来保存中位数,取定第一个元素,赋值给mid,即作为初始的中位数;
3、依次遍历后面的每一个数据,如果比mid小,则插入大顶堆;否则插入小顶堆;
4、如果大顶堆和小顶堆上的数据个数相差为2,则将mid插入到元素个数较少的堆中,然后从元素个数较多的堆中删除根节点,并将跟节点赋值给mid;
5、重复步骤3和4,直到所有的数据遍历结束;
此时,mid保存了一个数,再加上两个堆中保存的数,就构成了给定数据的集合。
如果两个堆中元素个数相等,则mid即为最终的中位数;否则,元素较多的堆的根节点元素与mid的和求平均值,即为最终的中位数。
public class HeapSort3 {
public static void adjustMaxHeap(List<Integer> list,int lastindex){
for (int i = (lastindex-1)/2; i>=0 ; i--) {
int k=i;
while(k*2+1<=lastindex){
int biggerindex=k*2+1;
if(biggerindex<lastindex){//防止溢出
if(list.get(biggerindex)<list.get(biggerindex+1)){
biggerindex++;
}
}
if(list.get(k)<list.get(biggerindex)){
swap(list,k,biggerindex);
k=biggerindex;
}else{
break;
}
}
}
}
public static void adjustMinHeap(List<Integer> list,int lastindex){
//i初始值为最后一个非子节点的索引
for (int i = (lastindex-1)/2; i>=0 ; i--) {
int k=i;
while(2*k+1<=lastindex){
int smallerindex=k*2+1;
if(smallerindex<lastindex){//防止越界
if(list.get(smallerindex)>list.get(smallerindex+1)){//左孩子值大于有孩子则交换
smallerindex++;
}
}
if(list.get(k)>list.get(smallerindex)){
swap(list,k,smallerindex);
k=smallerindex;
}else{
break;
}
}
}
}
public static void swap(List<Integer> list,int i,int j){
int temp=list.get(i);
list.set(i,list.get(j));
list.set(j,temp);
}
private static void getMiddle(List<Integer> list) {
if(list.size()==1){
System.out.println("中位数为:"+list.get(0));
return;
}
List<Integer> maxlist=new ArrayList<Integer>();//左堆-->大顶堆
List<Integer> minlist=new ArrayList<Integer>();//右堆-->小顶堆
int maxlen=0;//大顶堆内结点个数
int minlen=0;//小顶堆内结点个数
int mid=list.get(0);//中位数
for (int i = 1; i <list.size() ; i++) {
if(mid>list.get(i)){
maxlist.add(list.get(i));
maxlen++;
adjustMaxHeap(maxlist,maxlen-1);
}else{
minlist.add(list.get(i));
minlen++;
adjustMinHeap(minlist,minlen-1);
}
if(minlen-maxlen>1){
//maxlist.add(mid);
//adjustMaxHeap(maxlist,maxlen);
maxlist.add(0,mid);
mid=minlist.get(0);
minlist.remove(0);
maxlen++;
minlen--;
}
if(maxlen-minlen>1){
// minlist.add(mid);
// adjustMinHeap(minlist,minlen);
minlist.add(0,mid);
mid=maxlist.get(0);
maxlist.remove(0);
maxlen--;
minlen++;
}
}
if(minlen>maxlen){
mid=(mid+minlist.get(0))/2;
}else if(minlen<maxlen){
mid=(mid+maxlist.get(0))/2;
}
System.out.println("中位数为:"+mid);
}
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
list.add(2);
list.add(20);
list.add(13);
list.add(18);
list.add(15);
list.add(8);
list.add(3);
list.add(5);
list.add(4);
list.add(25);
getMiddle(list);
}
}