【排序算法】——冒泡排序、选择排序、插入排序、Shell排序等排序原理及Java实现
排序
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 //遍历打印排序后的数组
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实现的更多相关文章
- php基础排序算法 冒泡排序 选择排序 插入排序 归并排序 快速排序
<?php$arr=array(12,25,56,1,75,13,58,99,22);//冒泡排序function sortnum($arr){ $num=count($arr); ...
- C语言中的排序算法--冒泡排序,选择排序,希尔排序
冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...
- 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较
2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...
- 数据结构和算法(Golang实现)(19)排序算法-冒泡排序
冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...
- Python排序算法——冒泡排序
有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10786904.html 一.冒泡排序(Bubb ...
- 排序算法--冒泡排序(Bubble Sort)_C#程序实现
排序算法--冒泡排序(Bubble Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困 ...
- Python排序算法之选择排序定义与用法示例
Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...
- js 实现排序算法 -- 冒泡排序(Bubble Sort)
原文: 十大经典排序算法(动图演示) 冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来.走访数列的工作 ...
- Java 排序算法-冒泡排序及其优化
Java 排序算法-冒泡排序及其优化 什么是冒泡排序 基本写法 优化后写法 终极版本 源码及测试 什么是冒泡排序 这里引用一下百度百科上的定义: 冒泡排序(Bubble Sort),是一种计算机科学领 ...
- 使用 js 实现十大排序算法: 冒泡排序
使用 js 实现十大排序算法: 冒泡排序 冒泡排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
随机推荐
- DeWeb 与 Unigui的区别
DeWeb 与 Unigui 相同: 都是采用Delphi开发网页的平台 不同: 1 DeWeb不需要安装控件, 而Unigui需要安装自己的控件 2 DeWeb无需要学习HTML/CSS/JavaS ...
- 记录 mysql 使用时遇到的问题
1,linux平台上mysqld和mysql的区别. 首先,mysql数据库是标准的c/s架构,yum安装时注意到了,有mysql和mysql-server包 mysql是客户端的工具,mysqld ...
- windows端口占用处理方法
(1)输入命令:netstat -ano,列出所有端口的情况.在列表中我们观察被占用的端口,比如是8081,首先找到它.C:\Users\Administrator>netstat -ano活动 ...
- adb 安装与使用(一)
一.ADB简介 1. 什么是adb? adb(Android Debug Bridage)是Android sdk的一个工具: adb 是用来连接安卓手机和PC端的桥梁,要有adb作为二者之间的维系, ...
- Java中禁止浏览器开启缓存的方法命令
响应头里添加禁止浏览器缓存的内容 Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 其中,C ...
- 菜鸡的Java笔记 第三十二 - java 静态导入的实现
静态导入的实现 为了理解静态导入的操作产生的动机,下面通过一个具体的代码来观察 范例:现在有一个 Import 的类,这个类中的方法全部都是 static 方法 packa ...
- go语言并发编程
引言 说到go语言最厉害的是什么就不得不提到并发,并发是什么?,与并发相关的并行又是什么? 并发:同一时间段内执行多个任务 并行:同一时刻执行多个任务 进程.线程与协程 进程: 进程是具有一定独立功能 ...
- 模数不超过 long long 范围时的快速乘
笔者的话:使用前请确保评测系统的long double严格为16B ! 模数不在 int 范围内的乘法在 OI 中运用广泛,例如Millar-Rabin,Pollard-Rho等等.这样的乘法,直接乘 ...
- VS调用别人的COM组件的问题
调用第三方的COM组件,记得要先在管理员cmd执行:regsvr32 xxxx.dll 没执行之前运行 HRESULT hr = pComm.CreateInstance("xxxx.Com ...
- 区分wsgi、uWSGI、uwsgi、php-fpm、CGI、FastCGI
在学习Python web开发时候,可能会遇到诸如uwsgi,wsgi等名词,下面通过梳理总结探究它们之间的关系. CGI CGI,(Common Gateway Interface)通用网关接口,是 ...