归并排序
思路: 看到上面那个门没有?看到上面那两排小屁孩没有?它们要比身高,谁长的矮谁就先进去!
具体思路:
public static int[] helper;
创建一个辅助空间System.arraycopy(A, p, helper, p, r - p + 1);
将A数组赋值到辅助空间helperint left = p;
最左边下标int right = mid + 1; 中间右一个下标
int current = p;
将数据存入helper的下标left <= mid && right <= r
定格left要小于中间,right要小于rif(helper[left] <= helper[right])
A[current++] = helper[left++]; A[current++] = helper[right++];
判断谁小,谁小就装进A数组去- 这样做完后,左边指针可能没到头;右边的没到头也没关系,想想为什么?
- 因为我们是拷贝过去的,所以右侧没过完没关系。
- 但是如果是左侧没过完的话。
while (left <= mid) {
A[current] = helper[left];
current++;
left++;
}
具体具体代码:
{3,4,8,10 | 1,2,9,12}
- 3和1进行比较
- A{1} ,
{3, 4, 8, 10 | 2, 9, 12}
- 3和2进行比较
- A{1, 2} ,
{3, 4, 8, 10 | 9, 12}
- 3和9进行比较
- A{1,2,3} ,
{4, 8, 10 | 9, 12}
- 4和9进行比较
- A{1,2,3,4} ,
{8, 10 | 9, 12}
- 8和9进行比较
- A{1,2,3,4,8} ,
{10 | 9, 12}
- 10和9进行比较
- A{1,2,3,4,8,9} ,
{10 | 12}
- 10和12进行比较
- A{1,2,3,4,8,9,10,12}
代码
public class 归并排序 {
public static int[] helper;
//用来创建辅助空间的
public static void sort(int[] arr){
helper = new int[arr.length];
sort(arr, 0, arr.length - 1);
}
public static void sort(int[] A,int p,int r){
if(p < r){
int mid = p+((r-p)>>1);
sort(A, p, mid); //对左侧排序
sort(A,mid+1, r); //对右侧排序
merge(A, p, mid, r); //合并
}
}
public static void merge(int[] A,int p,int mid,int r){
//拷贝到辅助空间的相同位置
System.arraycopy(A, p, helper, p, r - p + 1);
int left = p;
int right = mid + 1;
int current = p;
while(left <= mid && right <= r){
if(helper[left] <= helper[right]){
A[current++] = helper[left++];
}else{
A[current++] = helper[right++];
}
}
// 这样做完后,左边指针可能没到头;右边的没到头也没关系,想想为什么?
while (left <= mid) {
A[current] = helper[left];
current++;
left++;
}
}
public static void main(String[] args){
int[] arr = {9,9,6,7,5,4,2,2,1};
Util.print(arr);
sort(arr);
System.out.println();
Util.print(arr);
}
}