zoukankan      html  css  js  c++  java
  • 几种排序算法及Java实现排序的几种方式

    几种排序算法

    下面的例子介绍了4种排序方法: 冒泡排序, 选择排序, 插入排序, 快速排序

      1 package date201709.date20170915;
      2 
      3 public class SortUtil {
      4 
      5     private static int quickSortTimes = 1;
      6 
      7     /**
      8      * 冒泡排序:<br>
      9      * 两层循环,每次循环比较前后两个元素,如果他们的顺序错误就把他们交换过来,一次循环后最终会把最大的数沉到数列的末端<br>
     10      * 下次循环时,上次循环沉到数列的末端的数不用再参与到本次循环中来比较<br>
     11      */
     12     // 第1次排序结果: 30 59 12 46 15 83 10 59 27 91
     13     // 第2次排序结果: 30 12 46 15 59 10 59 27 83 91
     14     // 第3次排序结果: 12 30 15 46 10 59 27 59 83 91
     15     // 第4次排序结果: 12 15 30 10 46 27 59 59 83 91
     16     // 第5次排序结果: 12 15 10 30 27 46 59 59 83 91
     17     // 第6次排序结果: 12 10 15 27 30 46 59 59 83 91
     18     // 第7次排序结果: 10 12 15 27 30 46 59 59 83 91
     19     // 第8次排序结果: 10 12 15 27 30 46 59 59 83 91
     20     // 第9次排序结果: 10 12 15 27 30 46 59 59 83 91
     21     public static void bubbleSort(int[] nums) {
     22         int temp = 0;
     23         int size = nums.length;
     24         for (int i = 0; i < size - 1; i++) {
     25             for (int j = 0; j < size - 1 - i; j++) {
     26                 if (nums[j] > nums[j + 1]) {
     27                     temp = nums[j];
     28                     nums[j] = nums[j + 1];
     29                     nums[j + 1] = temp;
     30                 }
     31             }
     32             printLog(nums, i + 1);
     33         }
     34     }
     35 
     36     /**
     37      * 选择排序:<br>
     38      * 在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环<br>
     39      */
     40     // 第1次排序结果: 10 83 59 12 46 15 91 30 59 27
     41     // 第2次排序结果: 10 12 59 83 46 15 91 30 59 27
     42     // 第3次排序结果: 10 12 15 83 46 59 91 30 59 27
     43     // 第4次排序结果: 10 12 15 27 46 59 91 30 59 83
     44     // 第5次排序结果: 10 12 15 27 30 59 91 46 59 83
     45     // 第6次排序结果: 10 12 15 27 30 46 91 59 59 83
     46     // 第7次排序结果: 10 12 15 27 30 46 59 91 59 83
     47     // 第8次排序结果: 10 12 15 27 30 46 59 59 91 83
     48     // 第9次排序结果: 10 12 15 27 30 46 59 59 83 91
     49     public static void selectSort(int[] nums) {
     50         int temp = 0;
     51         int size = nums.length;
     52         for (int i = 0; i < size - 1; i++) {
     53             // 记录每一次循环最小值的位置
     54             int pos = i;
     55             for (int j = i + 1; j < size; j++) {
     56                 if (nums[pos] > nums[j]) {
     57                     pos = j;
     58                 }
     59             }
     60             // 最小的数与第i个位置的数交换
     61             temp = nums[i];
     62             nums[i] = nums[pos];
     63             nums[pos] = temp;
     64 
     65             printLog(nums, i + 1);
     66         }
     67     }
     68 
     69     /**
     70      * 插入排序<br>
     71      * 每步将一个待排序的记录,按其大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。<br>
     72      */
     73     // 第1次排序结果: 30 83 59 12 46 15 91 10 59 27
     74     // 第2次排序结果: 30 59 83 12 46 15 91 10 59 27
     75     // 第3次排序结果: 12 30 59 83 46 15 91 10 59 27
     76     // 第4次排序结果: 12 30 46 59 83 15 91 10 59 27
     77     // 第5次排序结果: 12 15 30 46 59 83 91 10 59 27
     78     // 第6次排序结果: 12 15 30 46 59 83 91 10 59 27
     79     // 第7次排序结果: 10 12 15 30 46 59 83 91 59 27
     80     // 第8次排序结果: 10 12 15 30 46 59 59 83 91 27
     81     // 第9次排序结果: 10 12 15 27 30 46 59 59 83 91
     82     private static void insertSort(int[] nums) {
     83         int temp = 0;
     84         int size = nums.length;
     85         // 从第2个元素开始,第1个元素可以认为已经被排序
     86         for (int i = 1; i < size; i++) {
     87             // 取出下一个元素
     88             temp = nums[i];
     89             // 在已经排序的元素序列中从前向后扫描
     90             for (int j = 0; j < i; j++) {
     91                 // 假如temp比前面的某个值小,则将这个值及之后的值后移
     92                 if (temp < nums[j]) {
     93                     for (int k = i; k > j; k--) {
     94                         nums[k] = nums[k - 1];
     95                     }
     96                     nums[j] = temp;
     97                     break;
     98                 }
     99             }
    100 
    101             printLog(nums, i);
    102         }
    103     }
    104 
    105     /**
    106      * 快速排序:<br>
    107      * 选取当前数组段的第一个数作为中轴,和最后一个比,如果比它小交换,比它大(或相等)不做任何处理<br>
    108      * 交换了以后再和小的那端比,比它小不交换,比他大交换<br>
    109      * 这样循环往复,一趟排序完成,左边就是比中轴小的,右边就是比中轴大的,然后再递归对左边和右边的数组排序<br>
    110      */
    111     // 第1次排序结果: 27 10 15 12 30 46 91 59 59 83
    112     // 第2次排序结果: 12 10 15 27 -- -- -- -- -- --
    113     // 第3次排序结果: 10 12 15 -- -- -- -- -- -- --
    114     // 第4次排序结果: -- -- -- -- -- 46 91 59 59 83
    115     // 第5次排序结果: -- -- -- -- -- -- 83 59 59 91
    116     // 第6次排序结果: -- -- -- -- -- -- 59 59 83 --
    117     // 第7次排序结果: -- -- -- -- -- -- 59 59 -- --
    118     public static void quickSort(int[] numbers) {
    119         if (numbers.length > 1) {
    120             quickSort(numbers, 0, numbers.length - 1);
    121         }
    122     }
    123 
    124     private static void quickSort(int[] nums, int low, int high) {
    125         if (low < high) {
    126             // 选取中轴
    127             int middle = getMiddle(nums, low, high);
    128             printQuickSortLog(nums, low, high);
    129             if (low < middle - 1) {
    130                 // 对低字段表进行递归排序
    131                 quickSort(nums, low, middle - 1);
    132             }
    133             if (middle + 1 < high) {
    134                 // 对高字段表进行递归排序
    135                 quickSort(nums, middle + 1, high);
    136             }
    137         }
    138     }
    139 
    140     private static int getMiddle(int[] nums, int low, int high) {
    141         // 选取当前数组段的第一个数作为中轴
    142         int temp = nums[low];
    143         while (low < high) {
    144             // 比中轴大(或相等)不做任何处理(high--),直到找到比中轴小的
    145             while (low < high && nums[high] >= temp) {
    146                 high--;
    147             }
    148             // 比中轴小的记录移到低端
    149             nums[low] = nums[high];
    150             // 比中轴小不做任何处理(low++),直到找到比中轴大(或相等)的
    151             while (low < high && nums[low] < temp) {
    152                 low++;
    153             }
    154             // 比中轴大(或相等)的记录移到高端
    155             nums[high] = nums[low];
    156         }
    157         // 中轴记录到尾
    158         nums[low] = temp;
    159         // 返回中轴的位置
    160         return low;
    161     }
    162 
    163     private static void printLog(int[] nums, int times) {
    164         System.out.println("第" + times + "次排序结果:	" + formatNums(nums));
    165     }
    166 
    167     private static void printQuickSortLog(int[] nums, int low, int high) {
    168         System.out.println("第" + quickSortTimes++ + "次排序结果:	" + formatNums(nums, low, high));
    169     }
    170 
    171     private static String formatNums(int[] nums) {
    172         return formatNums(nums, 0, nums.length - 1);
    173     }
    174 
    175     private static String formatNums(int[] nums, int low, int high) {
    176         StringBuilder sb = new StringBuilder();
    177         for (int i = 0; i < low; i++) {
    178             sb.append("-- ");
    179         }
    180         for (int i = low; i <= high; i++) {
    181             sb.append(nums[i]).append(" ");
    182         }
    183         for (int i = high + 1; i < nums.length; i++) {
    184             sb.append("-- ");
    185         }
    186         return sb.toString().trim();
    187     }
    188 
    189     public static void main(String[] args) {
    190 
    191         // 10, 12, 15, 27, 30, 46, 59, 59, 83, 91
    192         int[] nums = { 30, 83, 59, 12, 46, 15, 91, 10, 59, 27 };
    193         // bubbleSort(nums);
    194         // selectSort(nums);
    195         // insertSort(nums);
    196         // quickSort(nums);
    197     }
    198 }

    Java实现排序的几种方式

    (1) 需要排序的Bean实现Comparable<T>接口

     1 package date201709.date20170915;
     2 
     3 import java.io.Serializable;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class User implements Serializable, Comparable<User> {
     8 
     9     private static final long serialVersionUID = 1L;
    10 
    11     private Integer id;
    12 
    13     private Integer age;
    14 
    15     private String name;
    16 
    17     public User(Integer id, Integer age, String name) {
    18         super();
    19         this.id = id;
    20         this.age = age;
    21         this.name = name;
    22     }
    23 
    24     public Integer getId() {
    25         return id;
    26     }
    27 
    28     public Integer getAge() {
    29         return age;
    30     }
    31 
    32     public String getName() {
    33         return name;
    34     }
    35 
    36     @Override
    37     public String toString() {
    38         return "User [id=" + id + ", age=" + age + ", name=" + name + "]";
    39     }
    40 
    41     @SuppressWarnings("serial")
    42     public static List<User> init() {
    43         return new ArrayList<User>() {
    44             {
    45                 add(new User(5, 31, "Zhang San"));
    46                 add(new User(2, 28, "Li Si"));
    47                 add(new User(3, 26, "Wang Wu"));
    48                 add(new User(1, 23, "Zhao Liu"));
    49                 add(new User(4, 26, "Liu Qi"));
    50             }
    51         };
    52     }
    53 
    54     // 比较ID从而对User排序
    55     @Override
    56     public int compareTo(User o) {
    57         return this.getId().compareTo(o.getId());
    58     }
    59 }
     1 package date201709.date20170915;
     2 
     3 import java.util.Collections;
     4 import java.util.List;
     5 
     6 public class UserTest {
     7 
     8     public static void main(String[] args) {
     9         // (1) Id升序
    10         List<User> userList = User.init();
    11         Collections.sort(userList);
    12         printList(userList);
    13 
    14         // (2) Id降序
    15         Collections.reverse(userList);
    16         printList(userList);
    17     }
    18 
    19     private static void printList(List<User> param) {
    20         param.forEach(p -> {
    21             System.out.println(p.toString());
    22         });
    23     }
    24 }

    (2) 使用内部类实现Comparator<T>接口

     1 package date201709.date20170915;
     2 
     3 import java.util.Collections;
     4 import java.util.Comparator;
     5 import java.util.List;
     6 
     7 public class UserTest {
     8 
     9     public static void main(String[] args) {
    10         // (1) Age升序
    11         List<User> userList = User.init();
    12         Collections.sort(userList, new AgeComparator());
    13         printList(userList);
    14 
    15         // (2) Age降序
    16         Collections.reverse(userList);
    17         printList(userList);
    18     }
    19 
    20     private static void printList(List<User> param) {
    21         param.forEach(p -> {
    22             System.out.println(p.toString());
    23         });
    24     }
    25 
    26     static class AgeComparator implements Comparator<User> {
    27         @Override
    28         public int compare(User o1, User o2) {
    29             return o1.getAge().compareTo(o2.getAge());
    30         }
    31     }
    32 }

    (3) 使用匿名内部类实现Comparator<T>接口

     1 package date201709.date20170915;
     2 
     3 import java.util.Collections;
     4 import java.util.Comparator;
     5 import java.util.List;
     6 
     7 public class UserTest {
     8 
     9     public static void main(String[] args) {
    10         // (1) Age升序
    11         List<User> userList = User.init();
    12         Collections.sort(userList, new Comparator<User>() {
    13             @Override
    14             public int compare(User o1, User o2) {
    15                 return o1.getAge().compareTo(o2.getAge());
    16             }
    17         });
    18         printList(userList);
    19 
    20         // (2) Age降序
    21         Collections.reverse(userList);
    22         printList(userList);
    23     }
    24 
    25     private static void printList(List<User> param) {
    26         param.forEach(p -> {
    27             System.out.println(p.toString());
    28         });
    29     }
    30 }

    (4) 使用lambda表达式

     1 package date201709.date20170915;
     2 
     3 import java.util.Collections;
     4 import java.util.List;
     5 
     6 public class UserTest {
     7 
     8     public static void main(String[] args) {
     9         // (1) Age升序
    10         List<User> userList = User.init();
    11         Collections.sort(userList, (a, b) -> (a.getAge().compareTo(b.getAge())));
    12         printList(userList);
    13 
    14         // (2) Age降序
    15         Collections.reverse(userList);
    16         printList(userList);
    17     }
    18 
    19     private static void printList(List<User> param) {
    20         param.forEach(p -> {
    21             System.out.println(p.toString());
    22         });
    23     }
    24 }

    (5) 使用stream及::表达式

     1 package date201709.date20170915;
     2 
     3 import java.util.Comparator;
     4 import java.util.List;
     5 import java.util.stream.Collectors;
     6 
     7 public class UserTest {
     8 
     9     public static void main(String[] args) {
    10         // (1) Age升序
    11         List<User> userList = User.init();
    12         List<User> result1 = userList.stream().sorted((a, b) -> a.getAge().compareTo(b.getAge()))
    13                 .collect(Collectors.toList());
    14         printList(result1);
    15 
    16         // (2) Age降序
    17         List<User> result2 = userList.stream().sorted(Comparator.comparing(User::getAge).reversed())
    18                 .collect(Collectors.toList());
    19         printList(result2);
    20     }
    21 
    22     private static void printList(List<User> param) {
    23         param.forEach(p -> {
    24             System.out.println(p.toString());
    25         });
    26     }
    27 }
  • 相关阅读:
    [转载]单点登录SSO:概述与示例
    Go实现基于WebSocket的弹幕服务
    Redis事务涉及的watch、multi等命令
    PHP实现快速排序
    PHP实现单例模式
    PHP实现二分法查找
    PHP实现冒泡排序
    Mac包管理神器Homebrew
    Mac超快速搭建Nginx、PHP、PHPStorm、XDebug环境
    修改CentOS服务器时间为北京时间
  • 原文地址:https://www.cnblogs.com/storml/p/7542300.html
Copyright © 2011-2022 走看看