希尔排序(Shell Sort)又称为缩小增量排序(diminishing increment sort)
该算法是一种泛化的插入排序。
希尔排序也称为n间距(n-gap)插入排序。希尔排序分多路并使用不同的间距来比较元素,通过逐步减少间距,最终以1为间距进行排序。
public static void shellSort(int[] array) {
// 先获取数组元素的个数
int length = array.length;
// 数组元素
int temp;
// 内循环的循环变量,在外部声明,避免重复创建
int i, j;
// 控制增量序列
for (int gap = length / 2; gap > 0; gap /= 2) {
// 在固定的增量序列下分组比较数组元素
for (i = gap; i < length; i++) {
temp = array[i];
j = i;
// 数据交换,此处的while循环是为了处理gap=1的情况
while ((j >= gap) && (array[j - gap] > temp)) {
array[j] = array[j - gap];
j -= gap;
}
array[j] = temp;
}
}
}
归并排序(Merge Sort)
参考:http://blog.csdn.net/yinjiabin/article/details/8265827/
public static void mergeSort(int[] array, int left, int right) {
if (right > left) {
int mid = (left + right) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, mid + 1, right);
}
}
/**
* 合并数据块
* @param array 原始数组
* @param left 数据块的起始位置
* @param mid 数据块的中间位置
* @param right 数据块的最后位置
*/
public static void merge(int[] array, int left, int mid, int right) {
// 左侧数据块的结束位置
int left_end = mid - 1;
// 左右两侧数据块元素的个数
int size = right - left + 1;
// 临时数组用来存储排好序的数据
int[] temp = new int[array.length];
// 临时数组的下标
int temp_pos = left;
// 确保数据在合法的数据块范围内
while ((left <= left_end) && (mid <= right)) {
if (array[left] <= array[mid]) {
temp[temp_pos] = array[left];
temp_pos++;
left++;
} else {
temp[temp_pos] = array[mid];
temp_pos++;
mid++;
}
}
// 处理左侧的数据块
while (left <= left_end) {
temp[temp_pos] = array[left];
temp_pos++;
left++;
}
// 处理右侧的数据块
while (mid <= right) {
temp[temp_pos] = array[mid];
temp_pos++;
mid++;
}
// 将临时数组中的元素赋值给原数组
for (int i = 0; i < size; i++) {
array[right] = temp[right];
right--;
}
}
快速排序(Quick Sort)也称为分区交换排序
思路:
1.如果数组中只有一个元素或者没有数据需要排序则直接返回
2.选择数组中的一个元素作为中心点(pivot),通常选择数组最右侧的元素
3.把数组分为两部分,一部分是元素大于中心点,一部分是元素小于中心点
4.递归处理两部分数组
public static void quickSort(int[] array, int low, int high) {
if (high > low) {
int pivot = partition(array, low, high);
quickSort(array, low, pivot - 1);
quickSort(array, pivot + 1, high);
}
}
/**
* 查找中心点位置,并根据中心点分组
* @param array 原始数组
* @param low 数组的起始位置
* @param high 数组的结束位置
* @return 中心点位置
*/
public static int partition(int[] array, int low, int high) {
// 默认选取数组最左边元素为中心点
int pivot_item = array[low];
// 数组的起始位置
int left = low;
// 数组的结束为止
int right = high;
while (left < right) {
// 从数组左侧开始找大于中心点的位置
while (left <= high && (array[left] <= pivot_item)) {
left++;
}
// 从数组右侧开始找小于中心点的位置
while (right >= low && (array[right] > pivot_item)) {
right--;
}
// 交换左侧找到的大于中心点值和右侧找到的小于中心点值
if (left < right) {
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}
}
// rught就是中心点的最终位置
array[low] = array[right];
array[right] = pivot_item;
return right;
}