几种排序算法

下面的例子介绍了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. }

几种排序算法及Java实现排序的几种方式的更多相关文章

  1. 常见排序算法总结 -- java实现

    常见排序算法总结 -- java实现 排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间 ...

  2. 7种基本排序算法的Java实现

    7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 /** * 直接插 ...

  3. 几种简单的排序算法(JAVA)

    几种排序算法(JAVA) 一.代码 package com.hdwang; import java.util.Arrays; /** * Created by admin on 2017/1/20. ...

  4. 七种经典排序算法及Java实现

    排序算法稳定性表示两个值相同的元素在排序前后是否有位置变化.如果前后位置变化,则排序算法是不稳定的,否则是稳定的.稳定性的定义符合常理,两个值相同的元素无需再次交换位置,交换位置是做了一次无用功. 下 ...

  5. 几大排序算法的Java实现

    很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...

  6. Java常见排序算法之直接选择排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  7. 排序算法及其java实现

    各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一.冒泡排序(BubbleSort) 1. 基本思 ...

  8. 十大经典排序算法(java实现、配图解,附源码)

    前言: 本文章主要是讲解我个人在学习Java开发环境的排序算法时做的一些准备,以及个人的心得体会,汇集成本篇文章,作为自己对排序算法理解的总结与笔记. 内容主要是关于十大经典排序算法的简介.原理.动静 ...

  9. 常见排序算法(附java代码)

    常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...

随机推荐

  1. zencart设置特价商品价格

    登录后台-工具-安装SQL脚本(Install SQL Patches) 运行以下语句: , '0001-01-01'); 红色部分请替换成实际要设置的数据:1234表示产品ID,888表示特价.

  2. 部署NFS共享

    一:NFS工作原理 什么是NFS服务器 NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器.不同的操作系统可以共享彼此的文件. NFS服务器可以让PC将 ...

  3. .net core 读取appsettings 的配置

    { "Logging": { "IncludeScopes": false, "LogLevel": { "Default&quo ...

  4. 浅析Service Worker

    一.service worker是什么? 平常浏览器窗口中跑的页面运行的是主JavaScript线程,DOM和window全局变量都是可以访问的. Service Worker是走的另外的线程,可以理 ...

  5. hive元数据

    本文介绍Hive元数据库中一些重要的表结构及用途,方便Impala.SparkSQL.Hive等组件访问元数据库的理解. 1.存储Hive版本的元数据表(VERSION) 该表比较简单,但很重要. V ...

  6. nginx跨站访问,防盗链

    跨站访问 从网站A利用AJAX跨站访问网站B 浏览器会根据服务端返回的头部信息(Access-Control-Allow-Origin)判断是否允许跨域访问.如果服务端都允许跨站访问,浏览器段也就没必 ...

  7. python--AutoPy库

    包括用于控制键盘和鼠标,在屏幕上查找颜色和位图以及显示警报的功能 - 所有这些都是以跨平台,高效和简单的方式进行的.适用于Mac OS X,Windows和X11 中文文档:https://blog. ...

  8. CSS3 animation属性 实现转动效果

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  9. jquery clearQueue方法 语法

    jquery clearQueue方法 语法 作用:clearQueue() 方法停止队列中所有仍未执行的函数.与 stop() 方法不同,(只适用于动画),clearQueue() 能够清除任何排队 ...

  10. vps能ping通但是ssh无法连接

    一.全国ping测试网页https://tools.ipip.net/ping.php 如果100%丢包率,那么肯定被q了,如果没有,也不一定没被q,进入下一步 二.国内外端口扫描测试http://t ...