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

Java关于排序的介绍3-高级排序

2016-03-04 09:53 531 查看
本篇博客主要是介绍-希尔排序快速排序

希尔排序

希尔排序是基于插入排序(关于插入排序的介绍请查看简单排序)。

希尔排序主要是解决了插入排序复制次数太多的问题。例如对一个序列进行从小到大的排序,如果有一个很小的数据在序列的末尾,那么当对该数据进行操作的时候,他左边已经有序的数据需要进行大量的进行右移复制操作。希尔排序会选择一个合理的间隔,开始进行排序,这样实现了数据的大跨度移动,就避免了大量数据的复制操作。

关键点间隔(h)的计算

这个地方不做详细介绍,感兴趣的同学请自行查看相关书籍

- java数据结构和算法

- 算法

这里使用 h=3*h+1 来计算间隔

下面看代码

public static void sort(int arr[]) {
int size = arr.length; // 获取数组大小
int h = 1; // 间隔
// 计算间隔
while (h < size / 3) {
h = h * 3 + 1;
}
while (h > 0) {
// 对h间隔组成的数据进行排序
for (int i = h; i < size; i++) {
int j = i;
int temp = arr[i];
// 进行判断 将比当前位置大的数据进行移动
while (j > h - 1 && arr[j - h] > temp) {
arr[j] = arr[j - h];
j -= h;
}
arr[j] = temp; // 将当前这次排序的标记数据进行移动
}
h = (h - 1) / 3; // 修改间隔
}
}


快速排序

快速排序的一个关键理解点是划分算法,还有要注意关键字的选择

下面看代码

/**
* 排序
* @param arrs 数组
* @param left 左边边界
* @param right 右边边界
*/
public static void sort(int arrs[], int left, int right) {
if (left >= right) {
return;
}
int x = arrs[right]; // 选取特定值 选择每一组里面的最后一个元素作为特定值
int leftPtr = divide(arrs, x, left, right); // 进行一次划分 结果 特定值左边都是小于特定值的数,特定值右边的都是大于特定值的数
// 再次进行排序 不必要在对上次特定值进行处理
sort(arrs, left, leftPtr - 1);
sort(arrs, leftPtr + 1, right);
}

/**
* 划分
* @param arrs 数组
* @param x 特定值
* @param left 左边边界
* @param right 右边边界
* @return 特定值的位置
*/
private static int divide(int arrs[], int x, int left, int right) {
int leftPtr = left - 1;
int rightPtr = right;
while (true) {
while (arrs[++leftPtr] > x);// 从左边第一个元素开始,顺序查找到第一个比特定值大的数
while (rightPtr > 0 && arrs[--rightPtr] < x); // 从倒数第二个元素开始,顺序查找到第一个比特定值小的数
if (leftPtr >= rightPtr) { // 已经划分完成
break;
}
// 进行交换
swap(arrs, leftPtr, rightPtr);
}
// 交换特定值到合适的位置
swap(arrs, leftPtr, right);
return leftPtr;
}

/**
* 交换数组里面俩个位置的值
* arrs 数据源
* leftPtr 左边索引
* rightPtr 右边的索引
*/
private static void swap(int[] arrs, int leftPtr, int rightPtr) {
int temp = arrs[leftPtr];
arrs[leftPtr] = arrs[rightPtr];
arrs[rightPtr] = temp;
}


其中divide就是实现了划分的方法

关于特定值的选择,本例是用每次划分的最后一个元素作为特定值,也有使用从第一个数、中间的一个数、末尾的一个数取一个中间的数作为特定值的。

关于排序的介绍系列博客就结束,在博客的结尾给出关于各个排序的时间复杂度

简单排序 - O(N^2)

归并排序 - O(N*logN)

希尔排序 - O(N*(logN)^2)

快速拍戏 - O(N*logN)

简单排序里面虽然时间复杂度都一样,但是一般情况下

冒泡 > 选择 > 插入

冒泡每次比较以后都需要进行数据交换操作。

归并排序的缺点需要新开辟一个与被排序的数组等大的数组空间。

希尔排序是基于插入排序的主要是减少数据复制次数,实现了数据的大跨度移动。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: