您的位置:首页 > 编程语言 > Java开发

[置顶] java 堆排序

2017-03-26 14:27 239 查看
一、堆排序是什么

  是对树形选择排序进一步的改进,以弥补树形选择排序占用空间多的遗憾。采用堆排序的时候,需要一个记录大小的辅助空间,这个空间很小。堆排序的过程中将向量中储存的数据看作是是一颗完全二叉树,利用完全二叉树中双亲结点和孩子结点之间的内在关系选择关键字最小的记录。即排序记录仍采用向量数组方式存储,并非采用树的存储方式,而只是采用完全二叉树的顺序结构的特征。

二、算法思想

    将待排序的关键字放在一个数组里k[1...n],将k看作是一颗完全二叉树的顺序表示,每个节点表示一个记录,第一个看k[1]记录作为二叉树的根,k[2]到k
按顺序排列,任意结点k[i]的做孩子是k[2i],右孩子是k[2i+1],双亲是k[i/2]。对这颗完全二叉树调整建堆。

    称各结点的关键字值满足条件:k[i].key>=r[2i].key;且k[i].key>=k[2i+1]的完全二叉树为大根堆,反之,若这颗完全二叉树中的任意结点的关键值都小于等于它的左孩子和右孩子的关键值(当有左孩子和右孩子时)则称为小根堆。

三、实现步骤

建堆->使得前n-1个元素调整为堆,具体看代码

package com.lzq.relect;

/**
* Created by lzqon 2017/3/26.
*/
public class HeapSort {
public static void filt(int[] a, int k, int m) {
int bg = a[k];//存储根节点上的数据
int i = k;//定义开始索引
int j = 2 * i;//根结点的左子树
boolean finished = false;
while (j <= m && !finished) {
if (j + 1 <= m && a[j] < a[j + 1])/**判断是否存在右子树,若有则将右子树的坐标赋值给左子树,沿右分支筛选*/
j = j + 1;
if (bg >= a[j]) /*判断自己的左/右子树是否大于本身*/
{
finished = true;//若左右子树不大于自身,则结束
} else {
/*反之,则将自己的左/右子树赋值给自己,如此往复*/
a[i] = a[j];
i = j;
j = 2 * i;
}
}
a[i]=bg;//最后把根上的值放到对应的位置
}

/**
*初始化堆:从数组的第n/2中间开始把所有子树调整为堆,逐层向上倒退,直到根结点
* @param a 数组
* @param n 数组的长度
*/
public static void crt_heap(int[] a, int n){
for(int i=n/2;i>=1;--i){
filt(a,i,n);
}
}

static  void HeapSortMethod(int[] a,int n){
crt_heap(a,n);//建立堆
for (int i = n; i>=2 ; --i) {/*堆顶元素此时为最大,只要循环将前i-1个元素调整为堆*/
int b=a[1];
4000
a[1]=a[i];
a[i]=b;
filt(a,1,i-1);
}
}

public static void main(String args[]){
int aa[]={1,2,6,8,5,6};
HeapSortMethod(aa,5);
for (int i:aa) {
System.out.println(i);
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: