合并排序 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;
}
}

浙公网安备 33010602011771号