排序

1.定义:
所谓排序,即是整理文件中的内容,使其按照关键字递增或递减的顺序进行排列。
输入:n个记录,n1,n2……,其对应1的关键字为k1,k2……
输出:n(i1),n(i2)……,使得k(i1)<=k(i2)……
(形象点讲就是排排坐,调座位,高在前低在后;或者低在前高在后)
2.排序算法的评价的专业术语
(1)稳定性
稳定:在排序的文件中,若存在多个关键字相同的记录,经过排序后,这些具有相同
关键字的记录之间的相对顺序不会发生改变。
不稳定:若具有相同关键字记录之间的相对次序发生改变,则成为不稳定的排序算法。
(2)复杂度
时间复杂度:一个算法执行所需消耗的时间。
空间复杂度:运行完该程序所需要的内存大小
(3)排序方式
内排序:在排序过程中,整个文件放在内存中进行处理,不涉及数据的内外存交换。
(适用于记录个数不是很多的小文件)
外排序:排序过程中要进行数据的内、外存交换。
(适用于记录个数多,不能将其一次性放入内存中的大文件)

交换排序

思想:对排序记录的关键字进行两两比较,发现次序相反时则进行交换直至没有次序相反的记录。
主要排序方法:冒泡排序、选择排序

冒泡排序

(1)算法描述:
冒泡排序是一种简单的排序,每次访问要排序的数组序列,一次比较相邻两个元素的大小,
若顺序错误就进行交换。(这个方法名的由来是小的元素慢慢“浮”在数组顶端,也可称为沉底(大的元素))
(2)算法的实现
a.比较相邻的两个元素大小,如果第一个大于第二个元素的大小就进行交换
b.对每一对相邻的元素都进行同样的操作,从第一对到最后一对,经过此步骤
最大的元素将是最后的元素。
c.针对所有的元素重复上述操作,除过最后一个。
d.重复a-c步骤,直至排序完成
 1 /**
2 *@Description: 排序算法
3 *@Author: dyy
4 */
5 public class Sort {
6 public static void main(String[] args) {
7 int [] arr = new int[]{4,2,1,6,3,6,0,-5,1,1};
8 bubbleSort(arr);
9 //遍历打印排序后的数组![image](https://note.youdao.com/favicon.ico)
10 for(int i = 0; i < arr.length;i++){
11 System.out.print(arr[i]+" ");
12 }
13 }
14 /**
15 *冒泡排序
16 * @date: 2018/8/15 11:27
17 */
18 public static void bubbleSort(int[] array){
19 //对数组进行临界判断
20 if(array==null||array.length==0){
21 System.out.println("array is NULL");
22 }
23 for(int i = 0; i < array.length - 1; i++){
24 //进行相邻元素额大小比较(也可循环至array.length-1,
25 // 循环至array.length-i-1是因为没经过一圈的排序后面的元素则就是有序的)
26 for(int j = 0;j < array.length-i-1;j++){
27 if(array[j]>array[j+1]){
28 swap(array,j,j+1);
29 }
30 }
31 }
32 }
33 /**
34 *实现数组中两个数的交换
35 * target为要交换的数组,x,y为要交换数字的下标
36 * @date: 2018/8/15 11:30
37 */
38 public static void swap(int[] target,int x,int y){
39 int temp = target[x];
40 target[x] = target[y];
41 target[y] = temp;
42 }
43 }

选择排序

(1)算法描述:选择排序是一种简单直观的排序算法。
它的工作原理是首先在未排序的序列中找到最大(小)的元素放置序列起始位置。
再从未排序序列中继续寻找元素放置已排序序列的尾部直至所有元素都有序。
(2)算法的实现:
a.初始状态:R[1……n]无序,有序数组为空
b.经过第i次扫描:R[1……i-1]有序,R[i……n]无序
c.经过n-1趟排序,为有序序列
 1  /**
2 *选择排序
3 * @date: 2018/8/15 12:26
4 */
5 public static void selectSort(int[] array){
6 //临界条件判断
7 if(array==null||array.length==0){
8 System.out.println("array is NULL");
9 }
10 //做第i趟排序
11 for(int i = 0; i < array.length-1;i++){
12 for(int j = i+1; j < array.length;j++){
13 //选出最小的记录进行交换
14 if(array[i]>array[j]){
15 swap(array,i,j);
16 }
17 }
18 }
19 }

插入排序

(1)算法描述
插入排序也是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对已未排序
的序列的数据,在已经有序的序列中从后向前找并进行插入。但是在进行插入的过程中需
要不断的将已经排序好的数据进行移位操作。
(2)算法实现
a.从第一个数据开始,将该元素认为已经排序好的序列。
b.取出下一个元素,在已经排序好的元素序列中从后向前进行扫描。
c.如果该元素(排序好的元素)大于新的元素,则将该元素移动到下一个位置
d.重复步骤c,知道找到已排序好的元素小于或者等于新元素的位置
e.将新的元素插入到该位置
f.重复步骤b
 1 /**
2 *插入排序
3 * @date: 2018/8/15 19:42
4 */
5 public static void insertSort(int[] array){
6 //临界条件判断
7 if(array==null||array.length==0){
8 System.out.println("array is null");
9 }
10 for(int i = 0; i < array.length;i++){
11 //从下一个元素进行遍历,若新元素小于已经排序好的序列的元素进行交换
12 for(int j = i ;(j>0)&&(array[j-1]>array[j]);j--){
13 swap(array,j-1,j);
14 }
15 }
16 }

Shell排序(希尔排序)

(1)算法描述
希尔排序是插入排序的一种,其中心思想是将数据进行分组,然后对每一组
数据进行排序,在每一组数据有序后,可以利用插入排序对所有分组进行最
后一次排序。这样可以减少数据交换的次数,加快排序速度。
(2)算法实现
a.选择一个增序序列t(1),t(2)……t(n),其中t(n)=1
b.按照增量序列个数k,对序列进行k此排序
c.每次排序,根据对应的增量,分为若干个长度为m的子序列,分别对子序列
进行插入排序。当增量为1时一个序列来进行处理,表长即为整个序列的长度。
 1 /**
2 *Shell排序(希尔排序)
3 * @date: 2018/8/15 20:07
4 */
5 public static void shellSort(int[] array){
6 if(array==null||array.length==0){
7 System.out.println("array is null");
8 }
9 //分隔集合之间的长度(第一次假设为集合长度的一半)
10 int increment = 0;
11 //分隔集合之间的长度,每次为前一次的一半(最后一次为1)
12 for(increment = array.length/2;increment>0;increment = increment>>1){
13 for(int i = increment;i<array.length;i++){
14 for(int j = i - increment;j >= 0;j = j - increment){
15 if(array[i] < array[j]){
16 swap(array,i,j);
17 }
18 }
19 }
20 }
21 }

快速排序

(1)算法描述
快速排序是一种划分交换排序,采用分治的策略(分治法)。通过一趟排序
将待排序序列划分为两个独立的部分,其中一部分的记录的关键字均小于另
外一部分的关键字。 分法法的基本思想:将原问题分解为若干个规模更小但是结构和原问题相似
的子问题,递归地解决这些子问题,然后将这些子问题的解组合成原问题的解。
(2)算法实现
a.从数组序列中选择一个“基准元素”(此文中以每个序列第一个元素为准)
b.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准
值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,
该基准就处于数列的中间位置。这个称为分区操作
c.递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
 1 public class Sort {
2 public static void main(String[] args) {
3 int [] arr = new int[]{4,2,1,6,3,6,0,-5,1,1};
4 quickSort(arr,0,arr.length-1);
5 //遍历打印排序后的数组
6 for(int i = 0; i < arr.length;i++){
7 System.out.print(arr[i]+" ");
8 }
9 }
10 /**
11 *快速排序
12 * @exception: array为待排序序列,low为要排序序列的下界,high为要排序序列的上界
13 * @date: 2018/8/16 9:41
14 */
15 public static void quickSort(int[] array,int low,int high){
16 if(array==null||array.length==0){
17 System.out.println("array is null");
18 }
19 //划分后的基准元素
20 int standard;
21 //区间长度小于1不需要再进行排序
22 if(low>=high){
23 return;
24 }
25 //对low……high进行划分
26 standard = partition(array,low,high);
27 //对左区间进行递归排序
28 quickSort(array,low,standard-1);
29 //对右区间进行递归排序
30 quickSort(array,standard+1,high);
31 }
32 /**
33 *对区间进行划分
34 * @date: 2018/8/16 9:49
35 */
36 private static int partition(int[] array, int low, int high) {
37 //进行临界判断
38 if(array==null||array.length==0){
39 return 0;
40 }
41 //基准元素,以区间第一个元素为准
42 int standardValue = array[low];
43 //区间长度小于1不需要进行划分
44 if(low>=high){
45 return low;
46 }
47 //区间两端交替向中间扫描,直至low=high为止
48 while(low<high){
49 //(standardValue相当于在位置low上)
50 while((low<high)&&(standardValue<=array[high])){
51 //从右向左扫描,查找第一个关键字小于基准元素standardValue值的记录
52 high--;
53 }
54 //表示找到小于基准元素standardValue值的记录
55 if(low<high){
56 //相当于交换low和high位置的值
57 array[low++] = array[high];
58 }
59 //(standardValue相当于在位置high上)
60 while((low<high)&&(array[low]<=standardValue)){
61 //从左向右扫描,查找第一个关键字大于standardValue值的记录
62 low++;
63 }
64 //表示找到大于基准元素standardValue值的记录
65 if(low<high){
66 //交换low和high的值
67 array[high--] = array[low];
68 }
69 }
70 //基准位置被最后定位
71 array[low] = standardValue;
72 return low;
73 }
74 }

归并排序

(1)算法描述
归并算法是在归并操作上的一种有效的排序算法,同样采用分治法。是将已经有序
的子序列进行合并,得到完全的有序序列,即先使得子序列有序,再使子序列段有
序,将两个有序序列合并为一个有序序列,称为“二路合并”。
(2)算法实现
a.将长度为n的序列划分为长度为n/2的两个子序列。
b.分别对这两个子序列采用归并排序。
c.将这两个已经有序的子序列进行合并。
 1 public class Sort {
2 public static void main(String[] args) {
3 int [] arr = new int[]{4,2,1,6,3,6,0,-5,1,1};
4 quickSort(arr,0,arr.length-1);
5 mergeSort(arr);
6 //遍历打印排序后的数组
7 for(int i = 0; i < arr.length;i++){
8 System.out.print(arr[i]+" ");
9 }
10 }
11 /**
12 *归并排序
13 * array为待排序序列,left、right为序列的左右边界,temp为和原序列长度相等的临时序列
14 * @date: 2018/8/16 11:31
15 */
16 public static void mergeSort(int[] array){
17 //在排序前创建与原数组大小相等的临时数组,避免递归过程中频繁开辟空间
18 int[] temp = new int[array.length];
19 mergeSort(array,0,array.length-1,temp);
20 }
21 private static void mergeSort(int[] array,int left,int right,int[] temp){
22 if(left<right){
23 int mid = left + (right-left)/2;
24 //左半边序列进行归并排序,使得其有序
25 mergeSort(array,left,mid,temp);
26 //有半边序列进行归并排序,使得其有序
27 mergeSort(array,mid+1,right,temp);
28 //将两个子序列进行合并
29 merge(array,left,mid,right,temp);
30 }
31 }
32 private static void merge(int[] array,int left,int middle,int right,int[] temp){
33 if(array==null||array.length==0){
34 System.out.println("array is null");
35 }
36 //左序列指针指向
37 int leftPoint = left;
38 //有序列指针指向
39 int rightPoint = middle+1;
40 //临时数组的指针指向
41 int tempPoint = 0;
42 while (leftPoint<=middle&&rightPoint<=right){
43 if(array[leftPoint]<=array[rightPoint]){
44 temp[tempPoint++] = array[leftPoint++];
45 }else{
46 temp[tempPoint++] = array[rightPoint++];
47 }
48 }
49 //将左半序列中的元素添加至temp数组中
50 while (leftPoint<=middle){
51 temp[tempPoint++] = array[leftPoint++];
52 }
53 //将右半序列中的元素添加至temp数组中
54 while(rightPoint<=right){
55 temp[tempPoint++] = array[rightPoint++];
56 }
57 tempPoint = 0;
58 //将temp中元素拷贝至原数组中
59 while (left<=right){
60 array[left++] = temp[tempPoint++];
61 }
62 }
63 }

【排序算法】——冒泡排序、选择排序、插入排序、Shell排序等排序原理及Java实现的更多相关文章

  1. php基础排序算法 冒泡排序 选择排序 插入排序 归并排序 快速排序

    <?php$arr=array(12,25,56,1,75,13,58,99,22);//冒泡排序function sortnum($arr){    $num=count($arr);    ...

  2. C语言中的排序算法--冒泡排序,选择排序,希尔排序

    冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...

  3. 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较

    2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...

  4. 数据结构和算法(Golang实现)(19)排序算法-冒泡排序

    冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...

  5. Python排序算法——冒泡排序

    有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10786904.html 一.冒泡排序(Bubb ...

  6. 排序算法--冒泡排序(Bubble Sort)_C#程序实现

    排序算法--冒泡排序(Bubble Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困 ...

  7. Python排序算法之选择排序定义与用法示例

    Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...

  8. js 实现排序算法 -- 冒泡排序(Bubble Sort)

    原文: 十大经典排序算法(动图演示) 冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来.走访数列的工作 ...

  9. Java 排序算法-冒泡排序及其优化

    Java 排序算法-冒泡排序及其优化 什么是冒泡排序 基本写法 优化后写法 终极版本 源码及测试 什么是冒泡排序 这里引用一下百度百科上的定义: 冒泡排序(Bubble Sort),是一种计算机科学领 ...

  10. 使用 js 实现十大排序算法: 冒泡排序

    使用 js 实现十大排序算法: 冒泡排序 冒泡排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

随机推荐

  1. journalctl常用命令

    journalctl -xe 查看全部日志# 以flow形式查看日志 $ journalctl -f # 查看内核日志 $ journalctl -k # 查看指定服务日志 $ journalctl ...

  2. Eclipse简单介绍

    1.编码设置:Windows>preference>Workspace>Other-UTF-8>apply and close: 2.字体大小设置:Windows>pre ...

  3. SpringCloud升级之路2020.0.x版-30. FeignClient 实现重试

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 需要重试的场景 微服务系统中,会遇到在线发布,一般的发布更新策略是:启动一个新的,启动成功 ...

  4. Mysql - date、datetime、timestamp 的区别

    date.datetime 的区别 顾名思义,date 日期,datetime 日期时间,所以 date 是 datetime 的日期部分 MySQL 以 YYYY-MM-DD hh:mm:ss 格式 ...

  5. CMU Convex Optimization(凸优化)笔记1--凸集和凸函数

    CMU凸优化笔记--凸集和凸函数 结束了一段时间的学习任务,于是打算做个总结.主要内容都是基于CMU的Ryan Tibshirani开设的Convex Optimization课程做的笔记.这里只摘了 ...

  6. RocketMQ架构原理解析(二):消息存储

    一.概述 由前文可知,RocketMQ有几个非常重要的概念: broker 服务端,负责存储.收发消息 producer 客户端1,负责产生消息 consumer 客服端2,负责消费消息 既然是消息队 ...

  7. 《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)

    1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast,那么这个toast我们这边如何进行测试呢?今天宏哥就分两篇介绍一下. ...

  8. Codeforces 1137F - Matches Are Not a Child's Play(LCT)

    Codeforces 题面传送门 & 洛谷题面传送门 考虑将一个点 \(x\) 的编号变为当前所有点编号最大值 \(+1\) 会对每个点的删除时间产生怎么样的影响.由于编号最大的点肯定是最后一 ...

  9. Codeforces 891D - Sloth(换根 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 换根 dp 好题. 为啥没人做/yiw 首先 \(n\) 为奇数时答案显然为 \(0\),证明显然.接下来我们着重探讨 \(n\) 是偶数 ...

  10. Codeforces 1503E - 2-Coloring(组合数学)

    Codeforces 题目传送门 & 洛谷题目传送门 考虑什么样的 2-染色方式是符合题目要求的,首先蓝.黄颜色所形成的连通块个数必须 \(\le 2\),否则一定不合法,而显然如果两种颜色连 ...