|NO.Z.00050|——————————|BigDataEnd|——|Hadoop&MapReduce.V23|——|Hadoop.v23|MR算法扩展|MergeSort归并排序|QuickSort快速排序|
一、[MR算法扩展之MergeSort归并排序][MR算法扩展之QuickSort快速排序]:Mergesort归并排序

二、合并

三、合并细节

### --- 不断地将当前序列平均分割成 2个子序列
~~~ 直到不能再分割(序列中只剩 1个元素)
### --- 不断地将 2个子序列合并成一个有序序列
~~~ 直到最终只剩下 1个子序列
~~~ 时间复杂度:O(nlogn)
~~~ 空间复杂度:O(n)
四、QuickSort-快排

### --- 第一步
~~~ 从数组中选择一个轴点元素(Pivot element),一般选择0位置元素为轴点元素
### --- 第二步
~~~ 利用Pivot将数组分割成2个子序列
~~~ 将小于 Pivot的元素放在Pivot前面(左侧)
~~~ 将大于 Pivot的元素放在Pivot后面(右侧)
~~~ 等于Pivot的元素放哪边都可以(暂定放在左边)
### --- 第三步
~~~ 对子数组进行第一步,第二步操作,直到不能再分割(子数组中只有一个元素)

### --- 时间复杂度
~~~ 最坏情况:T(n)=T(n-1)+o(n)=o(n2)
~~~ 最好情况:T(n)=2*T(n/1)+o(n)=o(nlogn)

### --- 空间复杂度
~~~ 由于递归调用,每次类似折半效果所以空间复杂度是O(logn)
二、编程代码
### --- MergeSort
package com.yanqi;
public class MergeSort<T extends Comparable<T>> extends Sort<T> {
private T[] leftArray;
@Override
protected void sort() {
leftArray = (T[]) new Comparable[array.length >> 1]; //除2操作
sort(0, array.length);
}
// T(n) = T(n/2) + T(n/2) + O(n)
/**
* 对 [begin, end) 范围的数据进行归并排序
*/
private void sort(int begin, int end) {
if (end - begin < 2) {
return;
}
int mid = (begin + end) >> 1;
sort(begin, mid);
sort(mid, end);
merge(begin, mid, end);
}
/**
* 将 [begin, mid) 和 [mid, end) 范围的序列合并成一个有序序列
*/
private void merge(int begin, int mid, int end) {
int li = 0, le = mid - begin;
int ri = mid, re = end;
int ai = begin;
// 备份左边数组
for (int i = li; i < le; i++) {
leftArray[i] = array[begin + i];
}
// 如果左边还没有结束
while (li < le) {
if (ri < re && cmp(array[ri], leftArray[li]) < 0) {
array[ai++] = array[ri++];
} else {
array[ai++] = leftArray[li++];
}
}
}
}
### --- QuickSort
package com.yanqi;
public class QuickSort<T extends Comparable<T>> extends Sort<T> {
@Override
public void sort() {
sort(0,array.length);
}
/**
* 对 [begin, end) 范围的元素进行快速排序
* @param begin
* @param end
*/
public void sort(int begin, int end) {
if (end - begin < 2) {
return;
}
// 确定轴点位置 O(n)
int mid = pivotIndex(begin, end);
// 对子序列进行快速排序
sort(begin, mid);
sort(mid + 1, end);
}
/**
* 构造出 [begin, end) 范围的轴点元素
* @return 轴点元素的最终位置
*/
public int pivotIndex(int begin, int end) {
// 备份begin位置的元素
T pivot = array[begin];
// end指向最后一个元素
end--;
while (begin < end) {
while (begin < end) {
if (cmp(pivot, array[end]) < 0) { // 右边元素 > 轴点元素
end--;
} else { // 右边元素 <= 轴点元素
array[begin++] = array[end];
break;
}
}
while (begin < end) {
if (cmp(pivot, array[begin]) > 0) { // 左边元素 < 轴点元素
begin++;
} else { // 左边元素 >= 轴点元素
array[end--] = array[begin];
break;
}
}
}
// 将轴点元素放入最终的位置
array[begin] = pivot;
// 返回轴点元素的位置
return begin;
}
}
### --- Sort
package com.yanqi;
public class QuickSort<T extends Comparable<T>> extends Sort<T> {
@Override
public void sort() {
sort(0,array.length);
}
/**
* 对 [begin, end) 范围的元素进行快速排序
* @param begin
* @param end
*/
public void sort(int begin, int end) {
if (end - begin < 2) {
return;
}
// 确定轴点位置 O(n)
int mid = pivotIndex(begin, end);
// 对子序列进行快速排序
sort(begin, mid);
sort(mid + 1, end);
}
/**
* 构造出 [begin, end) 范围的轴点元素
* @return 轴点元素的最终位置
*/
public int pivotIndex(int begin, int end) {
// 备份begin位置的元素
T pivot = array[begin];
// end指向最后一个元素
end--;
while (begin < end) {
while (begin < end) {
if (cmp(pivot, array[end]) < 0) { // 右边元素 > 轴点元素
end--;
} else { // 右边元素 <= 轴点元素
array[begin++] = array[end];
break;
}
}
while (begin < end) {
if (cmp(pivot, array[begin]) > 0) { // 左边元素 < 轴点元素
begin++;
} else { // 左边元素 >= 轴点元素
array[end--] = array[begin];
break;
}
}
}
// 将轴点元素放入最终的位置
array[begin] = pivot;
// 返回轴点元素的位置
return begin;
}
}
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
浙公网安备 33010602011771号