package junior.DAY_01;
public class Code_01_Sort
{
public static void main(String[] args)
{
//初始化数组
int len = (int)(Math.random()*20);//随机生成20以内的数组长度
int[] arr = new int[len];
for(int i = 0; i < len; i++)//在数组内随机生成1000内的值
{
arr[i] = (int)(Math.random()*1000) ;
}
for(int i = 0; i < len; i++)//格式化输出数组
System.out.printf("%02d:%-4d\n",i,arr[i]);
heapSort(arr);
for(int i = 0; i < len; i++)//格式化输出数组
System.out.printf("%02d:%-+4d\n",i,arr[i]);
}
public static void heapSort(int[] arr)
{//概念
//完全二叉树:满二叉树或者满二叉树的过程树
//用数组表示完全二叉树:
//索引i的左节点索引为:i*2+1 i*2+2 如果越界,则表示无该节点
//索引i的父节点索引为:(i-1)/2
//大根堆:整棵树的最大值就是根节点,每颗子树的最大值就是该子树的头结点
//将数组调成最大堆的方式:数组中的每个元素都与父节点比较,如果比父节点大,则和父节点交换位置,
//交换位置后还 应继续与父节点比较,直至小于父节点为止
//将最大堆调成有序:将根节点与最后一个节点交换,这样就把最大值换到了最后,并保持最大值的位置不变
//将堆的范围-1(不理会最大值)。
//然后将根节点与较大的左右孩子节点作比较,如果孩子节点比较大,则交换位置;
//交换位置后继续与孩子节点比较,直至比孩子节点大
//循环上面的步骤
if(arr == null || arr.length < 2)
return;
for(int i = 0; i < arr.length; i++)//将数组调成最大堆
heapInsert(arr,i);
int heapSize = arr.length;
int tmp = arr[0];//将最大堆的根节点和未排序堆的最后一个节点交换位置
arr[0] = arr[heapSize-1];
arr[heapSize-1] = tmp;
heapSize--;//将堆最后一个节点划入已排序部分
while(heapSize > 0)//只要未排序部分还有元素,则继续循环
{
heapify(arr,0,heapSize);//重新将未排序部分调整成最大堆
tmp = arr[0];//将最大堆的根节点和未排序堆的最后一个节点交换位置
arr[0] = arr[heapSize-1];
arr[heapSize-1] = tmp;
heapSize--;//将堆最后一个节点划入已排序部分
}
}
public static void heapInsert(int[] arr, int index)
{//将数组调成最大堆的方式:数组中的每个元素都与父节点比较,如果比父节点大,则和父节点交换位置,
//交换位置后还 应继续与父节点比较,直至小于父节点为止
//往上走
while(arr[index] > arr[(index-1)/2])
{
int tmp = arr[index];
arr[index] = arr[(index-1)/2];
arr[(index-1)/2] = tmp;
index = (index-1)/2;
}
}
public static void heapify(int[] arr, int index, int size)
{//将未排序部分调成最大堆 index表示开始调整位置 size表示堆的大小
//往下走
int left = index*2 + 1;
while(left < size)//保证左孩子节点不越界
{
int largest = 0;//
if(left+1 < size)//找出左右孩子节点比较大的节点
{
if(arr[left] > arr[left+1])
largest = left;
else
largest = left+1;
}
else
largest = left;
if(arr[largest] < arr[index])//把较大的孩子节点与父节点比较
{//如果没能比父节点大,则停止
largest = index;
break;
}
else//如果较大的孩子节点比父节点大,则与父节点交换位置
{
int tmp = arr[largest];
arr[largest] = arr[index];
arr[index] = tmp;
index = largest;//交换之后再接着与孩子节点比较
left = index*2+1;
}
}
}
}
常见算法之排序(进阶部分)_堆排序_04
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.