java泛型排序之归并排序

来源:互联网 发布:淘宝助理mac版下载 编辑:程序博客网 时间:2024/05/04 08:27
package cqychen.algorithms.part01.charpter01;


import java.util.ArrayList;
import java.util.Scanner;


//此程序由cqychen编写,后续将继续跟进算法导论相应章节。
//本节主要的是归并排序,采用的是分治思想,即分而治之主要分为三个步骤
//1)分解
//2)解决
//3)合并
/**
 * 这里主要编写的是泛型类
 * @author cqychen
 *
 * @param <T>
 */
class GenericMergeSort<T extends Comparable<? super T>> {
  private ArrayList<T> a = new ArrayList<>();


  //编写相应的泛型方法
  void merge(Integer p, Integer len_next, Integer q) {
    Integer len1 = len_next - p + 1;
    Integer len2 = q - len_next;
    ArrayList<T> one = new ArrayList<T>();
    ArrayList<T> two = new ArrayList<T>();
    Integer i = 0;
    Integer j = 0;
    for (i = 0; i < len1; i++) {
      one.add(i, a.get(p + i));
    }
    for (j = 0; j < len2; j++) {
      two.add(j, a.get(len_next + j + 1));
    }
    one.trimToSize();
    two.trimToSize();
    //这里就不好加哨兵了。
    i = j = 0;
    Integer k=p;
    while(i<len1&&j<len2){
      if(one.get(i).compareTo(two.get(j))<0){
        a.set(k++, one.get(i++));
      }else{
        a.set(k++, two.get(j++));
      }
    }
    while(i<len1){
      a.set(k++, one.get(i++));
    }
    while(j<len2){
      a.set(k++, two.get(j++));
    }
  }


  void mergesort(Integer p, Integer q) {
    if (p < q) {
      Integer len_next = (p + q) / 2;
      mergesort(p, len_next);
      mergesort(len_next + 1, q);
      merge(p, len_next, q);
    }
  }


  //进行初始化操作
  void seta(ArrayList<T> a) {
    System.out.println("这里我们采用的是泛型类的方法,这里进行初始化操作:");
    this.a = a;
  }


  //打印结果
  void printa() {
    System.out.println("采用泛型的最后结果如下");
    for (int i = 0; i < a.size(); i++) {
      System.out.println(a.get(i));
    }
  }
}


/**
 * 主类
 * @author cqychen
 *
 */
public class MergeSort {
  //这里解决最后的合并问题。虽然在最开始写,但是是最后的步骤
  //这里需要假定数组a中,从p到len_next以及len_next+1到q都是有序的
  void Merge(Integer[] a, Integer p, Integer len_next, Integer q) {
    //这里可以通过插入排序来完成归并过程,但是那就没必要了。
    //这里还是采用的是以空间换取时间的方法。不然要归并排序何用啊\
    Integer len1 = len_next - p + 1;
    Integer len2 = q - len_next;
    Integer[] one = new Integer[len1 + 1];
    Integer[] two = new Integer[len2 + 1];
    Integer i = 0;
    Integer j = 0;
    for (i = 0; i < len1; i++) {
      one[i] = a[p + i];
    }
    for (j = 0; j < len2; j++) {
      two[j] = a[j + len_next + 1];
    }
    //加上哨兵。使用最大值来做哨兵.按道理说应该是无限大。找不到啊。有风险的这样。不过这个是实验性质的嘛
    one[len1] = Integer.MAX_VALUE;
    two[len2] = Integer.MAX_VALUE;
    i = j = 0;
    /*for (Integer k = p; k < q + 1; k++) {
      if (one[i] < two[j]) {
        a[k] = one[i];
        i++;
      } else {
        a[k] = two[j];
        j++;
      }
    }*/
    //这个是不采用哨兵的情况
    Integer k=p;
    while(i<len1&&j<len2){
      if(one[i]<two[j]){
        a[k++]=one[i++];
      }else{
        a[k++]=two[j++];
      }
    }
    while(i<len1){
      a[k++]=one[i++];
    }
    while(j<len2){
      a[k++]=two[j++];
    }
    
  }


  /**
   * 这里之所以需要定义p和q主要是在分解后的传递参数需要这样的数字,不然怎么传递啊
   * @param a
   * @param p
   * @param q
   * @return
   */
  Integer[] MergeSort(Integer[] a, Integer p, Integer q) {
    if (p < q) {
      Integer len_next = (p + q) / 2;
      //这里进行分解
      MergeSort(a, p, len_next);
      MergeSort(a, len_next + 1, q);
      Merge(a, p, len_next, q);//这里进行解决和归并
    }
    return a;
  }


  public static void main(String[] args) {
    // TODO Auto-generated method stub
    //首先定义一个普通的用于输入的数组。
    Integer[] oraginal = new Integer[] { 23, 423, 221, 434, 5, 35, 67, 5677, 45, 777, 998, 98, 33 };
    Integer len = oraginal.length;
    MergeSort mergesort = new MergeSort();
    mergesort.MergeSort(oraginal, 0, len - 1);//这里应该是len-1,因为我比较喜欢从一个点到另一个点,都是有数字的。
    System.out.println("采用归并排序得到的结果是:");
    for (Integer i = 0; i < len; i++) {
      System.out.println(oraginal[i]);
    }


    /**
     * 这里采用的是变长数组,同时使用的是泛型类来完成对其他类型的排序。
     */
    Scanner inputs = new Scanner(System.in);
    ArrayList<Integer> input2 = new ArrayList<>();
    for (Integer i = 0; i < 10; i++) {
      Integer inputnum = inputs.nextInt();
      input2.add(inputnum);
    }
    input2.trimToSize();//调整数组大小
    System.out.println("输入的数组大小是:" + input2.size());
    GenericMergeSort aa = new GenericMergeSort<>();
    aa.seta(input2);
    aa.mergesort(0, input2.size() - 1);
    aa.printa();
    //对字符串进行排序
    ArrayList<String> input3 = new ArrayList<>();
    for (Integer i = 0; i < 10; i++) {
      String inputnum = inputs.next();
      input3.add(inputnum);
    }
    input3.trimToSize();//调整数组大小
    aa.seta(input3);
    aa.mergesort(0, input3.size()-1);
    aa.printa();
  }
}
0 0
原创粉丝点击