合并排序 java

理论:

1.是利用分治法的思想,两两有序序列,再利用合并算法变为一个有序序列
2.有n个元素,那么就需要2^x=n,这个x就是需要几趟
3.需要进行n次合并,那么时间复杂度就是nlogn

方法一代码部分:

package lianxi;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class SelectionSort{


private final int SIZE = 10; // 定义排序序列的长度。调试阶段可以把这个值调小以方便调试。
private final int MAX = 100; //定义排序序列的最大值

public static void main(String[] args){//主函数入口				选择排序
	SelectionSort ss = new SelectionSort();		//创建对象
	List<Integer> data = ss.dataGenerator();
	
	// 把数字打印出来可以帮助调试程序
	System.out.print(" 未排序前: ");
	ss.print(data); 
	ss.merge_sort(data,0, data.size()-1);
	System.out.print(" 排序后: ");
	ss.print(data);
	if(ss.test(data)){
		System.out.println(" 排序成功 !");
	}
	else{
		System.out.println(" 排序不成功 !");
	}
	
}

/*
数据生成函数
*/
public List<Integer> dataGenerator(){
	List<Integer> data = new ArrayList<Integer>();
	Random generator = new Random(System.currentTimeMillis());//获取系统时间
	for(int i = 0; i < SIZE; i++){
		data.add(generator.nextInt(MAX));//长度小于我们设置的长度时往data数组中添加数据
	}
	return data;
}

/*
测试排序结果是否正确
*/
public boolean test(List<Integer> nums){
	for(int i = 0 ; i < SIZE - 1; i++){//检查i和i+1是否递增
		if(nums.get(i) > nums.get(i+1)){
			return false;
		}
	}
	return true;
}

/*
打印排序的序列
*/
public void print(List<Integer> nums){
	System.out.println(" ");
	for(int i = 0; i < SIZE; i++){
		System.out.print(nums.get(i)+ " ");//根据数组下标分别空一格输出内容
	}
	System.out.println(" ");
}

/*
合并排序的实现
*/
public List<Integer> merge_sort(List<Integer> nums,int left,int right){
	if(left==right){
		return nums;							//当左右相等的时候说明只有一位数,直接返回
		}
	if(left<right){
		int mid=(left+right)/2;					//找出中间位数
		merge_sort(nums,left,mid);				//nums数列的左半区
		merge_sort(nums,mid+1,right);			//nums数列的右半区
		merge(nums,left,right);					//合并函数
	}	
	return nums;
}

private List<Integer> merge(List<Integer> nums, int left, int right) {
	int m=right-left+1;							//m存储传进来的数列长度
	int B[] = new int [m];						//创建一个m长度的B数组
	int i=0,left0=left;							//i来标记B数组的下标,记录初始的left位置给left0
	int mid=(left+right)/2,k=mid+1;				//mid为中间位置,k为右半区的第一个数
	while((left<=mid)&&(k<=right)){				//循环当left在左半区范围和k在右半区范围
		if(nums.get(left)<nums.get(k)){			//判断如果左小右,则先存储左边数进有序数组B中
			B[i++]=nums.get(left++);			//把小的元素依次添加到排序好的B数组
		}else{
			B[i++]=nums.get(k++);
		}
	}
	if(left>mid){								//若右半区剩余,则直接放入排序好的B数组
		for(;k<=right;k++){
			B[i++]=nums.get(k);
		}
	}
	if(k>right){								//若左半区剩余,则直接放入排序好的B数组
		for(;left<=mid;left++){
			B[i++]=nums.get(left);
		}
	}
	for(int j = 0;j<m;j++){						//之后将B排序好的数组给nums数列
		nums.set(left0++,B[j]);
	}
	return nums;
}
}

方法二:

package lianxi;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class Merger{

private final int ASIZE = 5;  // 序列A的长度。调试阶段可以调小方便调试。
private final int BSIZE = 10;  // 序列B的长度。调试阶段可以调小方便调试。


public static void main(String[] args){
	Merger mm = new Merger();
	List<Integer> l1 = mm.dataGenerator(mm.ASIZE);
	List<Integer> l2 = mm.dataGenerator(mm.BSIZE);
	mm.print(l1); 
	mm.print(l2); 
	List<Integer> l3 = mm.merge(l1,l2);
	mm.print(l3);
	if(mm.test(l3)){
		System.out.println(" 合并成功 !");
	}
	else{
		System.out.println(" 合并失败 !");
	}	
}

/*
产生有序序列
*/
public List<Integer> dataGenerator(int size){
	List<Integer> data = new ArrayList<Integer>();
	Random generator = new Random(System.currentTimeMillis()*size);
	data.add(generator.nextInt(100));
	for(int i = 1; i < size; i++){
		data.add(data.get(i-1) + generator.nextInt(100));
	}
	return data;
}

/*
测试结果
*/
public boolean test(List<Integer> nums){
	for(int i = 0 ; i < nums.size() - 1; i++){
		if(nums.get(i) > nums.get(i+1)){
			return false;
		}
	}
	return true;
}

/*
打印序列
*/
public void print(List<Integer> nums){
	System.out.println(" ");
	for(int i = 0; i < nums.size(); i++){
		System.out.print(nums.get(i)+ " ");
	}
	System.out.println(" ");
}

/*
合并两个有序序列,并返回结果
*/
public List<Integer> merge(List<Integer> A, List<Integer> B){
	List<Integer> C = new ArrayList<Integer>();
	int n = A.size();
	int m = B.size();
	int i = 0,j=0;
	while(i<n && j<m){
		if(A.get(i)>B.get(j)){
			C.add(B.get(j));
			j++;
		}else{
			C.add(A.get(i));
			i++;
		}
	}
	if(i==n){
		for(;j<m;j++){
			C.add(B.get(j));
		}
	}else{
		for(;i<n;i++){
			C.add(A.get(i));
		}
	}
	return C;
}

}
posted @ 2021-03-21 12:29  网抑云黑胶SVIP用户  阅读(129)  评论(0)    收藏  举报