1  | 实验一  | 
##1 实现基于分治法的归并排序算法.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48package test_chen_921;
public class MergeSort {
	public static void main(String[] args) {
		int[] r = { 5,2,1,0};
		merge_sort(r, 0, r.length - 1);
		print(r);
	}
	private static void print(int[] r) {
		// TODO 打印数组
		for (int i : r) {
			System.out.print(" " + i);
		}
		System.out.println();
	}
	private static void merge_sort(int[] r, int low, int high) {
		// TODO  划分 合并
		if (low < high) {
			int mid = (low + high) / 2;
			merge_sort(r, low, mid);
			merge_sort(r, mid + 1, high);
			merge(r, low, mid, high);
		}
	}
	private static void merge(int[] r, int low, int mid, int high) {
		// TODO  归并两个有序数组
		int k = 0;
		int i = low;
		int j = mid + 1;
		int[] tmp = new int[high - low + 1];
		while (i <= mid && j <= high) {
			if (r[i] <= r[j])
				tmp[k++] = r[i++];
			else
				tmp[k++] = r[j++];
		}
		while (i <= mid)
			tmp[k++] = r[i++];
		while (j <= high)
			tmp[k++] = r[j++];
		for (int m : tmp)
			r[low++] = m;
	}
}
##2. 实现快速排序的算法,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45package test_chen_921;
public class quick_test {
	public static void main(String[] args) {
		int[] r = { 5, 8, 6, 4, 2, 3, 1, 7, 9, 0 };
		quick_sort(r, 0, r.length - 1);
		print(r);
	}
	private static void print(int[] r) {
		// TODO 打印数组
		for (int i : r) {
			System.out.print(" " + i);
		}
		System.out.println();
	}
	private static void quick_sort(int[] r, int low, int high) {
		// TODO 找中值,并左右递归
		if (low < high) {
			int mid = partion(r, low, high);
			// print(r);
			quick_sort(r, low, mid);
			quick_sort(r, mid + 1, high);
		}
	}
	private static int partion(int[] r, int low, int high) {
		// TODO 把数组段第一个数划分,并返回中间值的下标
		int pivot = r[low];// 记录pivot
		while (low < high) {
			while (low < high && r[high] > pivot)
				high--;
			if (low < high)
				r[low++] = r[high];
			while (low < high && r[low] < pivot)
				low++;
			if (low < high)
				r[high--] = r[low];
		}
		r[low] = pivot;
		return low;
	}
}
##3 逆序数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63package test_chen_921;
public class InverseNum {
	
	public static void main(String[] args) {
		int []r = {80, 70, 9,9};
		System.out.println(getInverseNum(r, 0, r.length-1));
	}
	private static int getInverseNum(int[] r, int low, int high) {
		// TODO 计算前一半的逆序数,计算后一半的逆序数,计算之间的逆序数,相加并返回
		if(low<high)
		{
			int mid=(low+high)/2;
			int front_num=getInverseNum(r,low,mid);
			int behind_num=getInverseNum(r,mid+1,high);
			int between_num=mergeInverseNum(r,low,mid,high);
			return front_num+behind_num+between_num;
		}
		return 0;
	}
	private static void print(int[] r) {
		// TODO 打印数组
		for (int i : r) {
			System.out.print(" " + i);
		}
		System.out.println();
	}
	
	private static int mergeInverseNum(int[] r, int low, int mid, int high) {
		// TODO 与归并排序一致
		int []tmp=new int[high-low+1];
		int k1=low;
		int k2=mid+1;
		int k3=0;
		int count=0;
		while(k1<=mid && k2<=high)
		{
			if(r[k1]<=r[k2])
				tmp[k3++]=r[k1++];
			else
			{
				tmp[k3++]=r[k2++];
				//一旦这个数(r[k1])大于r[k2],那么他后面的数必定大于r[k2];所以count来源于他后面的数目的个数。
				count += mid - k1 + 1; 
			}
			
		}
		
		while(k1<=mid)
			tmp[k3++]=r[k1++];
		while(k2<=high)
			tmp[k3++]=r[k2++];
		
		for(int m : tmp)
			r[low++]=m;
		
		return count;
	}
}
##4 重要逆序数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68package test_chen_921;
public class SignificantNum {
	public static void main(String[] args) {
		int[] r = { 80, 70, 9, 9 };
		System.out.println(getSignificantNum(r, 0, r.length - 1));
	}
	private static int getSignificantNum(int[] r, int low, int high) {
		// TODO 计算前一半的逆序数,计算后一半的逆序数,计算之间的逆序数,相加并返回
		if (low < high) {
			int mid = (low + high) / 2;
			int front_num = getSignificantNum(r, low, mid);
			int behind_num = getSignificantNum(r, mid + 1, high);
			int between_num = mergeSig	nificantNum(r, low, mid, high);
			return front_num + behind_num + between_num;
		}
		return 0;
	}
	private static void print(int[] r) {
		// TODO 打印数组
		for (int i : r) {
			System.out.print(" " + i);
		}
		System.out.println();
	}
	private static int mergeSignificantNum(int[] r, int low, int mid, int high) {
		// TODO 先记数,后排序
		int[] tmp = new int[high - low + 1];
		int k1 = low;
		int k2 = mid + 1;
		int k3 = 0;
		int count = 0;
		// count
		while (k1 <= mid && k2 <= high) {
			if (r[k1] <= 2 * r[k2])
				k1++;
			else {
				count += mid - k1 + 1;
				k2++;
			}
		}
		// merge
		k1 = low;
		k2 = mid + 1;
		while (k1 <= mid && k2 <= high) {
			if (r[k1] <= r[k2])
				tmp[k3++] = r[k1++];
			else
				tmp[k3++] = r[k2++];
		}
		while (k1 <= mid)
			tmp[k3++] = r[k1++];
		while (k2 <= high)
			tmp[k3++] = r[k2++];
		for (int m : tmp)
			r[low++] = m;
		return count;
	}
}