、
//每次将堆顶元素与最后的元素交换
public class HeapSort
{
public static void heapSort(DataWrap[] data)
{
System.out.println("开始排序");
int arrayLength = data.length;
//循环建堆
for (int i = 0; i < arrayLength - 1 ; i++ )//n-1次循环
{
//建堆
builMaxdHeap(data , arrayLength - 1 - i);
//交换堆顶和最后一个元素
swap(data , 0 , arrayLength - 1 - i);
System.out.println(java.util.Arrays.toString(data));
}
}
//对data数组从0到lastIndex建大顶堆
private static void builMaxdHeap(DataWrap[] data , int lastIndex)
{
//从lastIndex处节点(最后一个节点)的父节点开始
for (int i = (lastIndex - 1) / 2 ; i >= 0 ; i--)
{
//k保存当前正在判断的节点
int k = i;
//如果当前k节点的子节点存在
while (k * 2 + 1 <= lastIndex)
{
//k节点的左子节点的索引
int biggerIndex = 2 * k + 1;
//如果biggerIndex小于lastIndex,即biggerIndex + 1
//代表的k节点的右子节点存在
if (biggerIndex < lastIndex)
{
//如果右子节点的值较大
if(data[biggerIndex].compareTo(data[biggerIndex + 1]) < 0)
{
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
//如果k节点的值小于其较大子节点的值
if(data[k].compareTo(data[biggerIndex]) < 0)
{
//交换它们
swap(data , k , biggerIndex);
//将biggerIndex赋给k,开始while循环的下一次循环,
//重新保证k节点的值大于其左、右子节点的值。
k = biggerIndex;
}
else
{
break;
}
}
}
}
//交换data数组中i、j两个索引处的元素
private static void swap(DataWrap[] data , int i , int j)
{
DataWrap tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
public static void main(String[] args)
{
DataWrap[] data = {
new DataWrap(21 , ""),
new DataWrap(30 , ""),
new DataWrap(49 , ""),
new DataWrap(30 , "*"),
new DataWrap(21 , "*"),
new DataWrap(16 , ""),
new DataWrap(9 , "")
};
System.out.println("排序之前:/n"
+ java.util.Arrays.toString(data));
heapSort(data);
System.out.println("排序之后:/n"
+ java.util.Arrays.toString(data));
}
}
归并排序
public class MergeSort
{
//利用归并排序算法对数组data进行排序
public static void mergeSort(DataWrap[] data)
{
//归并排序
sort(data , 0 , data.length - 1);
}
/**
* 将索引从left到right范围的数组元素进行归并排序
* @param data 待排序的数组
* @param left 待排序的数组的第一个元素索引
* @param right 待排序的数组的最后一个元素的索引
*/
private static void sort(DataWrap[] data
, int left, int right)
{
if (left < right)
{
//找出中间索引
int center = (left + right) / 2;
//对左边数组进行递归
sort(data, left, center);
//对右边数组进行递归
sort(data, center + 1, right);
//合并
merge(data, left, center, right);
}
}
/**
* 将两个数组进行归并,归并前两个数组已经有序,归并后依然有序。
* @param data 数组对象
* @param left 左数组的第一个元素的索引
* @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right 右数组的最后一个元素的索引
*/
private static void merge(DataWrap[] data
, int left, int center, int right)
{
//定义一个与待排序序列长度相同的临时数组
DataWrap[] tmpArr = new DataWrap[data.length];
int mid = center + 1;
//third记录中间数组的索引
int third = left;
int tmp = left;
while (left <= center && mid <= right)
{
//从两个数组中取出小的放入中间数组
if (data[left].compareTo(data[mid]) <= 0)
{
tmpArr[third++] = data[left++];
}
else
{
tmpArr[third++] = data[mid++];
}
}
//剩余部分依次放入中间数组
while (mid <= right)
{
tmpArr[third++] = data[mid++];
}
while (left <= center)
{
tmpArr[third++] = data[left++];
}
//将中间数组中的内容复制拷回原数组
//(原left~right范围的内容复制回原数组)
while (tmp <= right)
{
data[tmp] = tmpArr[tmp++];
}
}
public static void main(String[] args)
{
DataWrap[] data = {
new DataWrap(9 , ""),
new DataWrap(-16 , ""),
new DataWrap(21 , "*"),
new DataWrap(23 , ""),
new DataWrap(-30 , ""),
new DataWrap(-49 , ""),
new DataWrap(21 , ""),
new DataWrap(30 , "*"),
new DataWrap(30 , "")
};
System.out.println("排序之前:/n"
+ java.util.Arrays.toString(data));
mergeSort(data);
System.out.println("排序之后:/n"
+ java.util.Arrays.toString(data));
}
}