几种排序算法及Java实现排序的几种方式

时间:2022-11-26 04:29:28

几种排序算法

下面的例子介绍了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 + "次排序结果:\t" + formatNums(nums));
165     }
166 
167     private static void printQuickSortLog(int[] nums, int low, int high) {
168         System.out.println("第" + quickSortTimes++ + "次排序结果:\t" + 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 }