1、直接选择排序
需要进行n-1次比较
每次将i位置的元素依次与之后的所有元素进行比较,若其大于则进行位置调换
实现代码:
public class DataWrap implements Comparable<DataWrap>
{
int data;
String flag;
public DataWrap(int data, String flag)
{
this.data = data;
this.flag = flag;
}
@Override
public int compareTo(DataWrap dataWrap)
{
return this.data > dataWrap.data ? 1 : (this.data == dataWrap.data ? 0
: -1);
}
public String toString()
{
return data + flag;
}
}
//直接选择排序
public class SelectSort
{
public static void main(String[] args)
{
DataWrap[] dataWraps =
{ new DataWrap(21, ""), new DataWrap(30, ""), new DataWrap(49, ""),
new DataWrap(30, "*"), new DataWrap(16, ""),
new DataWrap(9, "") };
System.out.println("排序之前:\n" + Arrays.toString(dataWraps));
selectSort(dataWraps);
System.out.println("排序之后:\n" + Arrays.toString(dataWraps));
}
public static void selectSort(DataWrap[] dataWraps)
{
System.out.println("排序开始。。。。。");
int arrayLength = dataWraps.length;
for (int i = 0; i < arrayLength - 1; i++)
{
// 保存本次比较中最小值的索引
int minIndex = i;
// 第i个数只需与后面的数比较
for (int j = i + 1; j < arrayLength; j++)
{
if (dataWraps[minIndex].compareTo(dataWraps[j]) > 0)
{
// 将当前获得的最小值索引赋值给minIndex
minIndex = j;
}
if (i != minIndex)
{
DataWrap tmp = dataWraps[i];
dataWraps[i] = dataWraps[minIndex];
dataWraps[minIndex] = tmp;
}
}
}
}
}
有n项数据,数据交换做多n-1次,但是比较次数较多,时间复杂度为O(n2)
空间复杂度为O(1)
2、堆排序
堆排序的建堆(大顶堆和小顶堆)
排序过程:
- 先将其转换成完全二叉树
- 完全二叉树的最后一个非叶子节点,也就是最后一个父节点。其索引值为(n-2)/2,如果其子节点大于它本身则与较大的子节点交换
- 向前处理前一个节点,直至根节点
- 交换堆顶和最后一个元素,将最后一个元素移除堆
- 重复2、3、4步骤
实现代码
//堆排序
public class HeapSort
{
public static void main(String[] args)
{
DataWrap[] dataWraps =
{ 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" + Arrays.toString(dataWraps));
heapSort(dataWraps);
System.out.println("排序之后:\n" + Arrays.toString(dataWraps));
}
public static void heapSort(DataWrap[] dataWraps)
{
System.out.println("开始排序。。。。");
int arrayLength = dataWraps.length;
// 循环建堆
for (int i = 0; i < arrayLength - 1; i++)
{
buildMaxdHeap(dataWraps, arrayLength - 1 - i);
// 交换堆顶和最后一个元素
swap(dataWraps, 0, arrayLength - 1 - i);
System.out.println(Arrays.toString(dataWraps));
}
}
private static void buildMaxdHeap(DataWrap[] dataWraps, 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 = k * 2 + 1;
// 如果biggerIndex小于lastIndex,即biggerIndex+1
// 代表的k节点的右子节点存在
if (biggerIndex < lastIndex)
{
// 如果右子节点的数据大
if (dataWraps[biggerIndex]
.compareTo(dataWraps[biggerIndex + 1]) < 0)
{
// 记录较大的子节点
biggerIndex++;
}
}
if (dataWraps[k].compareTo(dataWraps[biggerIndex]) < 0)
{
// 交换
swap(dataWraps, k, biggerIndex);
// 将biggerIndex赋值给k开始下一次循环
// 重新保证k节点的值大于其左右子节点
k = biggerIndex;
} else
{
break;
}
}
}
}
// 交换两个索引处元素位置
private static void swap(DataWrap[] dataWraps, int i, int j)
{
DataWrap tmp = dataWraps[i];
dataWraps[i] = dataWraps[j];
dataWraps[j] = tmp;
}
}
需要进行n-1次建堆,每次建堆消耗log2n,则时间复杂度为O(nlog2n)
空间复杂度为O(1)