几种排序算法及Java实现排序的几种方式
几种排序算法
下面的例子介绍了4种排序方法: 冒泡排序, 选择排序, 插入排序, 快速排序
- package date201709.date20170915;
- public class SortUtil {
- private static int quickSortTimes = 1;
- /**
- * 冒泡排序:<br>
- * 两层循环,每次循环比较前后两个元素,如果他们的顺序错误就把他们交换过来,一次循环后最终会把最大的数沉到数列的末端<br>
- * 下次循环时,上次循环沉到数列的末端的数不用再参与到本次循环中来比较<br>
- */
- // 第1次排序结果: 30 59 12 46 15 83 10 59 27 91
- // 第2次排序结果: 30 12 46 15 59 10 59 27 83 91
- // 第3次排序结果: 12 30 15 46 10 59 27 59 83 91
- // 第4次排序结果: 12 15 30 10 46 27 59 59 83 91
- // 第5次排序结果: 12 15 10 30 27 46 59 59 83 91
- // 第6次排序结果: 12 10 15 27 30 46 59 59 83 91
- // 第7次排序结果: 10 12 15 27 30 46 59 59 83 91
- // 第8次排序结果: 10 12 15 27 30 46 59 59 83 91
- // 第9次排序结果: 10 12 15 27 30 46 59 59 83 91
- public static void bubbleSort(int[] nums) {
- int temp = 0;
- int size = nums.length;
- for (int i = 0; i < size - 1; i++) {
- for (int j = 0; j < size - 1 - i; j++) {
- if (nums[j] > nums[j + 1]) {
- temp = nums[j];
- nums[j] = nums[j + 1];
- nums[j + 1] = temp;
- }
- }
- printLog(nums, i + 1);
- }
- }
- /**
- * 选择排序:<br>
- * 在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环<br>
- */
- // 第1次排序结果: 10 83 59 12 46 15 91 30 59 27
- // 第2次排序结果: 10 12 59 83 46 15 91 30 59 27
- // 第3次排序结果: 10 12 15 83 46 59 91 30 59 27
- // 第4次排序结果: 10 12 15 27 46 59 91 30 59 83
- // 第5次排序结果: 10 12 15 27 30 59 91 46 59 83
- // 第6次排序结果: 10 12 15 27 30 46 91 59 59 83
- // 第7次排序结果: 10 12 15 27 30 46 59 91 59 83
- // 第8次排序结果: 10 12 15 27 30 46 59 59 91 83
- // 第9次排序结果: 10 12 15 27 30 46 59 59 83 91
- public static void selectSort(int[] nums) {
- int temp = 0;
- int size = nums.length;
- for (int i = 0; i < size - 1; i++) {
- // 记录每一次循环最小值的位置
- int pos = i;
- for (int j = i + 1; j < size; j++) {
- if (nums[pos] > nums[j]) {
- pos = j;
- }
- }
- // 最小的数与第i个位置的数交换
- temp = nums[i];
- nums[i] = nums[pos];
- nums[pos] = temp;
- printLog(nums, i + 1);
- }
- }
- /**
- * 插入排序<br>
- * 每步将一个待排序的记录,按其大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。<br>
- */
- // 第1次排序结果: 30 83 59 12 46 15 91 10 59 27
- // 第2次排序结果: 30 59 83 12 46 15 91 10 59 27
- // 第3次排序结果: 12 30 59 83 46 15 91 10 59 27
- // 第4次排序结果: 12 30 46 59 83 15 91 10 59 27
- // 第5次排序结果: 12 15 30 46 59 83 91 10 59 27
- // 第6次排序结果: 12 15 30 46 59 83 91 10 59 27
- // 第7次排序结果: 10 12 15 30 46 59 83 91 59 27
- // 第8次排序结果: 10 12 15 30 46 59 59 83 91 27
- // 第9次排序结果: 10 12 15 27 30 46 59 59 83 91
- private static void insertSort(int[] nums) {
- int temp = 0;
- int size = nums.length;
- // 从第2个元素开始,第1个元素可以认为已经被排序
- for (int i = 1; i < size; i++) {
- // 取出下一个元素
- temp = nums[i];
- // 在已经排序的元素序列中从前向后扫描
- for (int j = 0; j < i; j++) {
- // 假如temp比前面的某个值小,则将这个值及之后的值后移
- if (temp < nums[j]) {
- for (int k = i; k > j; k--) {
- nums[k] = nums[k - 1];
- }
- nums[j] = temp;
- break;
- }
- }
- printLog(nums, i);
- }
- }
- /**
- * 快速排序:<br>
- * 选取当前数组段的第一个数作为中轴,和最后一个比,如果比它小交换,比它大(或相等)不做任何处理<br>
- * 交换了以后再和小的那端比,比它小不交换,比他大交换<br>
- * 这样循环往复,一趟排序完成,左边就是比中轴小的,右边就是比中轴大的,然后再递归对左边和右边的数组排序<br>
- */
- // 第1次排序结果: 27 10 15 12 30 46 91 59 59 83
- // 第2次排序结果: 12 10 15 27 -- -- -- -- -- --
- // 第3次排序结果: 10 12 15 -- -- -- -- -- -- --
- // 第4次排序结果: -- -- -- -- -- 46 91 59 59 83
- // 第5次排序结果: -- -- -- -- -- -- 83 59 59 91
- // 第6次排序结果: -- -- -- -- -- -- 59 59 83 --
- // 第7次排序结果: -- -- -- -- -- -- 59 59 -- --
- public static void quickSort(int[] numbers) {
- if (numbers.length > 1) {
- quickSort(numbers, 0, numbers.length - 1);
- }
- }
- private static void quickSort(int[] nums, int low, int high) {
- if (low < high) {
- // 选取中轴
- int middle = getMiddle(nums, low, high);
- printQuickSortLog(nums, low, high);
- if (low < middle - 1) {
- // 对低字段表进行递归排序
- quickSort(nums, low, middle - 1);
- }
- if (middle + 1 < high) {
- // 对高字段表进行递归排序
- quickSort(nums, middle + 1, high);
- }
- }
- }
- private static int getMiddle(int[] nums, int low, int high) {
- // 选取当前数组段的第一个数作为中轴
- int temp = nums[low];
- while (low < high) {
- // 比中轴大(或相等)不做任何处理(high--),直到找到比中轴小的
- while (low < high && nums[high] >= temp) {
- high--;
- }
- // 比中轴小的记录移到低端
- nums[low] = nums[high];
- // 比中轴小不做任何处理(low++),直到找到比中轴大(或相等)的
- while (low < high && nums[low] < temp) {
- low++;
- }
- // 比中轴大(或相等)的记录移到高端
- nums[high] = nums[low];
- }
- // 中轴记录到尾
- nums[low] = temp;
- // 返回中轴的位置
- return low;
- }
- private static void printLog(int[] nums, int times) {
- System.out.println("第" + times + "次排序结果:\t" + formatNums(nums));
- }
- private static void printQuickSortLog(int[] nums, int low, int high) {
- System.out.println("第" + quickSortTimes++ + "次排序结果:\t" + formatNums(nums, low, high));
- }
- private static String formatNums(int[] nums) {
- return formatNums(nums, 0, nums.length - 1);
- }
- private static String formatNums(int[] nums, int low, int high) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < low; i++) {
- sb.append("-- ");
- }
- for (int i = low; i <= high; i++) {
- sb.append(nums[i]).append(" ");
- }
- for (int i = high + 1; i < nums.length; i++) {
- sb.append("-- ");
- }
- return sb.toString().trim();
- }
- public static void main(String[] args) {
- // 10, 12, 15, 27, 30, 46, 59, 59, 83, 91
- int[] nums = { 30, 83, 59, 12, 46, 15, 91, 10, 59, 27 };
- // bubbleSort(nums);
- // selectSort(nums);
- // insertSort(nums);
- // quickSort(nums);
- }
- }
Java实现排序的几种方式
(1) 需要排序的Bean实现Comparable<T>接口
- package date201709.date20170915;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.List;
- public class User implements Serializable, Comparable<User> {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private Integer age;
- private String name;
- public User(Integer id, Integer age, String name) {
- super();
- this.id = id;
- this.age = age;
- this.name = name;
- }
- public Integer getId() {
- return id;
- }
- public Integer getAge() {
- return age;
- }
- public String getName() {
- return name;
- }
- @Override
- public String toString() {
- return "User [id=" + id + ", age=" + age + ", name=" + name + "]";
- }
- @SuppressWarnings("serial")
- public static List<User> init() {
- return new ArrayList<User>() {
- {
- add(new User(5, 31, "Zhang San"));
- add(new User(2, 28, "Li Si"));
- add(new User(3, 26, "Wang Wu"));
- add(new User(1, 23, "Zhao Liu"));
- add(new User(4, 26, "Liu Qi"));
- }
- };
- }
- // 比较ID从而对User排序
- @Override
- public int compareTo(User o) {
- return this.getId().compareTo(o.getId());
- }
- }
- package date201709.date20170915;
- import java.util.Collections;
- import java.util.List;
- public class UserTest {
- public static void main(String[] args) {
- // (1) Id升序
- List<User> userList = User.init();
- Collections.sort(userList);
- printList(userList);
- // (2) Id降序
- Collections.reverse(userList);
- printList(userList);
- }
- private static void printList(List<User> param) {
- param.forEach(p -> {
- System.out.println(p.toString());
- });
- }
- }
(2) 使用内部类实现Comparator<T>接口
- package date201709.date20170915;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- public class UserTest {
- public static void main(String[] args) {
- // (1) Age升序
- List<User> userList = User.init();
- Collections.sort(userList, new AgeComparator());
- printList(userList);
- // (2) Age降序
- Collections.reverse(userList);
- printList(userList);
- }
- private static void printList(List<User> param) {
- param.forEach(p -> {
- System.out.println(p.toString());
- });
- }
- static class AgeComparator implements Comparator<User> {
- @Override
- public int compare(User o1, User o2) {
- return o1.getAge().compareTo(o2.getAge());
- }
- }
- }
(3) 使用匿名内部类实现Comparator<T>接口
- package date201709.date20170915;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- public class UserTest {
- public static void main(String[] args) {
- // (1) Age升序
- List<User> userList = User.init();
- Collections.sort(userList, new Comparator<User>() {
- @Override
- public int compare(User o1, User o2) {
- return o1.getAge().compareTo(o2.getAge());
- }
- });
- printList(userList);
- // (2) Age降序
- Collections.reverse(userList);
- printList(userList);
- }
- private static void printList(List<User> param) {
- param.forEach(p -> {
- System.out.println(p.toString());
- });
- }
- }
(4) 使用lambda表达式
- package date201709.date20170915;
- import java.util.Collections;
- import java.util.List;
- public class UserTest {
- public static void main(String[] args) {
- // (1) Age升序
- List<User> userList = User.init();
- Collections.sort(userList, (a, b) -> (a.getAge().compareTo(b.getAge())));
- printList(userList);
- // (2) Age降序
- Collections.reverse(userList);
- printList(userList);
- }
- private static void printList(List<User> param) {
- param.forEach(p -> {
- System.out.println(p.toString());
- });
- }
- }
(5) 使用stream及::表达式
- package date201709.date20170915;
- import java.util.Comparator;
- import java.util.List;
- import java.util.stream.Collectors;
- public class UserTest {
- public static void main(String[] args) {
- // (1) Age升序
- List<User> userList = User.init();
- List<User> result1 = userList.stream().sorted((a, b) -> a.getAge().compareTo(b.getAge()))
- .collect(Collectors.toList());
- printList(result1);
- // (2) Age降序
- List<User> result2 = userList.stream().sorted(Comparator.comparing(User::getAge).reversed())
- .collect(Collectors.toList());
- printList(result2);
- }
- private static void printList(List<User> param) {
- param.forEach(p -> {
- System.out.println(p.toString());
- });
- }
- }
几种排序算法及Java实现排序的几种方式的更多相关文章
- 常见排序算法总结 -- java实现
常见排序算法总结 -- java实现 排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间 ...
- 7种基本排序算法的Java实现
7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 /** * 直接插 ...
- 几种简单的排序算法(JAVA)
几种排序算法(JAVA) 一.代码 package com.hdwang; import java.util.Arrays; /** * Created by admin on 2017/1/20. ...
- 七种经典排序算法及Java实现
排序算法稳定性表示两个值相同的元素在排序前后是否有位置变化.如果前后位置变化,则排序算法是不稳定的,否则是稳定的.稳定性的定义符合常理,两个值相同的元素无需再次交换位置,交换位置是做了一次无用功. 下 ...
- 几大排序算法的Java实现
很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...
- Java常见排序算法之直接选择排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
- 排序算法及其java实现
各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一.冒泡排序(BubbleSort) 1. 基本思 ...
- 十大经典排序算法(java实现、配图解,附源码)
前言: 本文章主要是讲解我个人在学习Java开发环境的排序算法时做的一些准备,以及个人的心得体会,汇集成本篇文章,作为自己对排序算法理解的总结与笔记. 内容主要是关于十大经典排序算法的简介.原理.动静 ...
- 常见排序算法(附java代码)
常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...
随机推荐
- python读取txt文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x8e in position 8: illegal multibyte sequence
python读取文件时报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x8e in position 8: illegal multibyte ...
- Android异常与性能优化相关面试问题-内存管理面试问题详解
内存管理机制概述: 分配机制:操作系统会为每一个进程分配一个合理的内存大小,从而保证每一个进程能够正常的运行,不至于内存不够使用,或者某个进程占用过多的内存. 回收机制:在系统内存不足的时候,系统有一 ...
- SpringBoot使用JPA来做数据查询
Spring-Data-JPA在做数据存储方面真的很方便,它的目的就是写更少的代码,更多的事情,但是也有其力有未逮或者说处理起来比较闹心的地方. 1.先来感受一下使用JPA做数据查询时,代码的简化程度 ...
- springmvc后台获取表单提交的数据——@ModelAttribute等方式
1.通过注解ModelAttribute直接映射表单中的参数到POJO.在from中的action写提交的路径,在input的name写参数的名称. package com.demo.model; p ...
- php类知识 self $this都只能在当前类中使用
$this是当前对象的指针,self是当前类的指针 $this只能用在成员方法中,不能存在于静态方法 self 静态方法和成员方法中都能使用 self可以访问类常量,静态属性,静态方法,成员方法--- ...
- Spring Security 解决X-Frame-Options deny
错误信息: Refused to display 'https://github.com/hwclass/awesome-sound' in a frame because it set 'X-Fra ...
- JavaScript算术运算符
㈠运算符(操作符) ⑴通过运算符可以对一个或多个值进行运算,并获取运算结果 ⑵比如:typeof就是运算符,可以来获得一个值得类型 它会将该值的类型以字符串的形式返回 ...
- php+大文件管理
用过浏览器的开发人员都对大文件上传与下载比较困扰,之前遇到了一个php文件夹上传下载的问题,无奈之下自己开发了一套文件上传控件,在这里分享一下.希望能对你有所帮助.此控件PC全平台支持包括mac,li ...
- BZOJ 3143: [Hnoi2013]游走 概率与期望+高斯消元
Description 一个无向连通图,顶点从1编号到N,边从1编号到M.小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获 ...
- python测试网站访问速度
# -*- coding: utf-8 -*- # @Author : Felix Wang # @time : 2018/8/13 22:13 # pip3 install pycurl impor ...