package com.Fengkuangjava.分治法;
import java.util.Scanner;
import java.util.Stack;
//归并排序的思想是:将数组一分为二,然后对左边排序,再对右边排序
//然后左边又一分为二,然后重复上面过程,右边也一分为二,重复上面过程
public class 归并排序 {
/**
*
* @param nums
* @param L 左边
* @param M 中间
* @param R 右边
*/
/* public static void Merage(int[] nums,int L,int M,int R){
int leftSize = M - L;
int rightSize = R - M + 1;
int[] left = new int[leftSize];
int[] right = new int[rightSize];
int i = 0,j = 0,k = 0;
//将左边的所有元素放入left数组中
for (i = L; i < M; i++) {
left[i-L] = nums[i];
}
//将右边的所有元素放入right数组中
for (j = M; j <=R; j++) {
right[j-M] = nums[j];
}
//合并排序两个数组
i = 0;
j = 0;
k = L;
while(i<leftSize&&j<rightSize){
if (left[i]<right[j]){
nums[k++]=left[i++];
}else{
nums[k++]=right[j++];
}
}
while(i<leftSize){//左边数组未完
nums[k++] = left[i++];
}
while(j<rightSize){//右边数组未完
nums[k++] = right[j++];
}
}
public static void mergeSort(int[] nums,int L,int R){
if (L==R){
return;
}
int M = (L+R)/2;
mergeSort(nums,L,M);//左边
mergeSort(nums,M+1,R);//右边
Merage(nums,L,M+1,R);
}*/
public static void mergeSort(int[] nums,int L,int R) {
if (L>=R){
return;
}
int mid = (L + R) / 2;//划分区间
mergeSort(nums, L, mid);//排序左区间
mergeSort(nums, mid + 1, R);//排序右区间
//排序
int i = L, j = mid + 1;
Stack<Integer> stack = new Stack<>();//定义一个栈
while (i <=mid&& j<=R) {//排序并入栈
if (nums[i] <= nums[j]) {
stack.push(nums[i++]);
} else {
stack.push(nums[j++]);
}
}
while (i <= mid) {//左数组没完
stack.push(nums[i++]);
}
while (j <= R) {//右数组没完
stack.push(nums[j++]);
}
for (int k = L,m = 0; m < stack.size();m++, k++) {
nums[k] = stack.get(m);
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("请输入数组长度n:");
int n = in.nextInt();
System.out.print("请输入数组元素:");
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = in.nextInt();
}
mergeSort(nums,0,n-1);
//输出
for (int i = 0; i < n; i++) {
System.out.print(nums[i]+" ");
}
}
}
void arrayMerge(int data[], int low, int center, int high){
//创建一个临时数组作为缓冲区用来临时存储两个合并好的数组元素值
int *p = (int*)malloc(sizeof(int)*(high - low));
int i = low;
int j = center;
int k = 0;//用来记录临时数组的下标
while (i < center&&j < high){
if (data[i] < data[j]){
p[k++] = data[i++];
}
else{
p[k++] = data[j++];
}
}
//将剩余的元素存入到数组中
while(i<center){
p[k++] = data[i++];
}
while (j < high){
p[k++] = data[j++];
}
//将临时数组中的元素复制到原数组中
for (i = 0, j = low; j < high; j++){
data[j] = p[i++];
}
//释放临时数组
free(p);
}
void mergeSort(int data[], int low, int high){
//如果当前序列中只剩下一个元素,返回
if (high-low== 1){
return;
}
int center = (high + low) / 2;
//左二分排序
mergeSort(data, low,center);
//右二分排序
mergeSort(data, center, high);
//合并两个升序数组
arrayMerge(data, low, center, high);
}
int main(void){
int data[8] = { 3, 2, 5, 8, 4, 7, 6, 9 };
mergeSort(data,0,8);
for (int i = 0; i < 8; i++){
printf("%d ",data[i]);
}
}