当前位置:   article > 正文

【Java】排序方法--归并排序_java 怎么将相同code排序在一起

java 怎么将相同code排序在一起

基本思想

同选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n*logn)的时间复杂度。代价是需要额外的内存空间。

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

算法描述:

算法诗:

将数组分为两半

对左半部分排序

对右半部分排序

合并左右两部分

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置

第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

第四步:重复步骤3直到某一指针超出序列尾,将另一序列剩下的所有元素直接复制到合并序列尾

动态图解释(来源网络):

 

实现方法接口:

方案一:

常规的递归思想:

  1. package 排序方法;
  2. import java.util.*;
  3. public class Merge{
  4. public static void MergeSort(int[] arr) {
  5. sort(arr, 0, arr.length - 1);
  6. }
  7. public static void sort(int[] arr, int L, int R) {
  8. if (L == R) {
  9. return;
  10. }
  11. int mid = (R + L) >> 1;
  12. sort(arr, L, mid);
  13. sort(arr, mid + 1, R);
  14. merge(arr, L, mid, R);
  15. }
  16. public static void merge(int[] arr, int L, int mid, int R) {
  17. int[] temp = new int[R - L + 1];
  18. int i = 0;
  19. int p1 = L;
  20. int p2 = mid + 1;
  21. while (p1 <= mid && p2 <= R) {// 比较左右两部分的元素,哪个小,把那个元素填入temp中
  22. temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
  23. }
  24. // 上面的循环退出后,把剩余的元素依次填入到temp中
  25. // 以下两个while只有一个会执行
  26. while (p1 <= mid) {//看是否有剩余元素
  27. temp[i++] = arr[p1++];
  28. }
  29. while (p2 <= R) {
  30. temp[i++] = arr[p2++];
  31. }
  32. // 把最终的排序的结果复制给原数组
  33. for (i = 0; i < temp.length; i++) {
  34. arr[L + i] = temp[i];
  35. }
  36. }
  37. public static void main(String[] args) {
  38. int[] a = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
  39. MergeSort(a);
  40. for (int i = 0; i < a.length; i++) {
  41. System.out.print(a[i] + " ");
  42. }
  43. }
  44. }

输出如图:

方案二:

先建立从Collection接口,再通过调用接口来实现:

  1. import java.util.Collections;
  2. import java.util.List;
  3. public class Collection {
  4. public static void sort(List list) {
  5. int l = 0;
  6. int r = list.size () - 1;
  7. //归并
  8. devide (list, l, r);
  9. }
  10. /**
  11. * 归:分治
  12. */
  13. private static void devide(List list, int left, int right) {
  14. int mid = (left + right) / 2;//计算中值索引
  15. // 归
  16. if (left < right) {
  17. devide (list, left, mid);
  18. devide (list, mid + 1, right);
  19. merge (list, left, mid, mid + 1, right);
  20. } else {
  21. //并
  22. merge (list, left, mid, mid + 1, right);
  23. }
  24. }
  25. /**
  26. * @param list
  27. * @param left
  28. * @param mid
  29. * @param i
  30. * @param right
  31. */
  32. private static void merge(List list, int left, int mid, int i, int right) {
  33. int index = left;
  34. Object[] temp = new Object[list.size ()];
  35. int ls = left, le = mid;//左边的起始索引和结束索引;
  36. int rs = i, re = right;//右边的起始索引和结束索引;
  37. //至少把一边的所有数组元素按顺序放入临时数组;
  38. while (ls <= le && rs <= re) {
  39. Comparable o1 = (Comparable) list.get (ls);
  40. Comparable o2 = (Comparable) list.get (rs);
  41. if (o1.compareTo (o2) == -1) {
  42. temp[index] = o1;
  43. ls++;
  44. } else {
  45. temp[index] = o2;
  46. rs++;
  47. }
  48. index++;
  49. }
  50. //判断左边是否有剩余元素
  51. if (ls <= le) {
  52. for (int j = ls; j <= le; j++) {
  53. temp[index++] = list.get (j);
  54. }
  55. }
  56. //判断右边是否有剩余元素
  57. if (rs <= re) {
  58. for (int j = rs; j <= re; j++) {
  59. temp[index++] = list.get (j);
  60. }
  61. }
  62. for (int j = left; j <= right; j++) {
  63. list.set (j, temp[j]);
  64. }
  65. }
  66. }

Test类:

  1. public class TestColections {
  2. public static void main(String[] args) {
  3. @Test
  4. public void test3(){
  5. List s = new ArrayList ();
  6. s.add (new Student (1001, "路飞", "M"));
  7. s.add (new Student (1030, "明哥", "M"));
  8. s.add (new Student (1002, "娜美", "W"));
  9. s.add (new Student (1010, "卡二", "M"));
  10. s.add (new Student (1008, "女帝", "W"));
  11. edu.xalead.Collection.sort(s);
  12. System.out.println (s);
  13. }
  14. }
  15. }

Student类:

  1. /**
  2. * 调用一个接口,接口的对象是对Student进行比较,
  3. * 比较是比较code,而不是其他的东西,所以要调用。
  4. */
  5. public class Student implements Comparable{
  6. private int Code;
  7. private String Name;
  8. private String Sex;
  9. public int getCode() {
  10. return Code;
  11. }
  12. public void setCode(int code) {
  13. Code = code;
  14. }
  15. public String getName() {
  16. return Name;
  17. }
  18. public void setName(String name) {
  19. Name = name;
  20. }
  21. public String getSex() {
  22. return Sex;
  23. }
  24. public void setSex(String sex) {
  25. Sex = sex;
  26. }
  27. @Override
  28. public String toString() {
  29. return "Student{" +
  30. "Code=" + Code +
  31. ", Name='" + Name + '\'' +
  32. ", Sex='" + Sex + '\'' +
  33. '}';
  34. }
  35. public Student(int code , String name, String sex) {
  36. this.Code = code;
  37. this.Name = name;
  38. this.Sex = sex;
  39. }
  40. /**
  41. *
  42. *
  43. *这是一个接口,对应于Comparable,也就是方法的接口,Student要进行比较是
  44. *比较它的code,所以要调用这个接口来比较。
  45. *
  46. * */
  47. public int compareTo(Object o){
  48. if(o instanceof Student){
  49. Student s = (Student) o;
  50. if(this.getCode () > s.getCode ()) return 1;
  51. else if(this.getCode () < s.getCode ()) return -1;
  52. return 0;
  53. }
  54. throw new RuntimeException("类型不对,无法匹配");
  55. }
  56. }

输出结果:

Student{Code=1001, Name='路飞', Sex='M'},

Student{Code=1002, Name='娜美', Sex='W'},

Student{Code=1008, Name='女帝', Sex='W'},

Student{Code=1010, Name='卡二', Sex='M'},

Student{Code=1030, Name='明哥', Sex='M'}

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/67036?site
推荐阅读
相关标签
  

闽ICP备14008679号