Java数据结构和算法(三)--三大排序--冒泡、选择、插入排序
三大排序在我们刚开始学习编程的时候就接触过,也是刚开始工作笔试会遇到的,后续也会学习希尔、快速排序,这里顺便复习一下
冒泡排序:
步骤:
1、从首位开始,比较首位和右边的索引
2、如果当前位置比右边的大,则交换位置
3、当前位置的索引向右移动一位,必须两两比较
图例:

代码实现:
public static int[] sort(int[] array) {
for (int i = 1; i < array.length; i++) { //外层循环,代表着需要经过多少轮比较
boolean flag = true;
for (int j = 0; j < array.length-i; j++) { //内层循环,两两比较,用来移动索引的,直到找到最大值,注意这里是array.length-i,当然-1也可以,只不过效率会降低,而且没必要
if (array[j]>array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = false;
}
}
if (flag) { //理论上,要经过N-1轮比较,但是如果在之前数据正好是有序的,直接break,减少了循环的次数,这就是flag的作用
break;
}
}
return array;
}
public static void display(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
public static void main(String[] args) {
int[] array = new int[]{77, 99, 33, 44 ,55, 11, 9, 101, 2};
System.out.print("排序前:");
display(array);
sort(array);
System.out.print("\r\n排序后:");
display(array);
}
输出结果:
排序前:77 99 33 44 55 11 9 101 2
排序后:2 9 11 33 44 55 77 99 101
上面代码中注释已经很明显了,而且冒泡排序很简单的,稍微看一遍,应该都可以写出来了
冒泡排序的效率:
第一轮,经过N-1次比较,第二轮是N-2次比较,理论上经过N-1轮:(N-1)+(N-2)+...+1=N*(N-1)/2,在N比较大的时候,可以约等于N^2/2
而数据交换的次数:如果数据完全是随机的,交换个可能是50%,那就是N^2/4
由于常数不算在大O算法中,可以忽略2和4,所以可以认为冒泡排序的时间复杂度O(N^2)
在任何情况,双层循环我们都可以认为时间复杂度O(N^2),因为外层为N次,内层为N或者几分之N
选择排序:
选择排序在冒泡排序的基础上进行了改进
步骤:
1、找到最小值的索引
2、如果最小值的索引不是首位,就交换
3、最小值的索引右移一位,继续比较
图例:

代码实现:
public static int[] sort(int[] array) {
for (int i = 0; i < array.length-1; i++) {
int min = i; //min为最小值的索引,默认为0
for (int j = i+1; j < array.length; j++) { //这里是j=i+1开始的,循环结束得到最小值的索引
if (array[min]>array[j]) {
min = j;
}
}
if (min != i) { //如果索引不是首位,就交换
int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
return array;
}
public static void display(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
public static void main(String[] args) {
int[] array = new int[]{77, 99, 33, 44 ,55, 11, 9, 101, 2};
System.out.print("排序前:");
display(array);
sort(array);
System.out.print("\r\n排序后:");
display(array);
}
输出结果:
排序前:77 99 33 44 55 11 9 101 2
排序后:2 9 11 33 44 55 77 99 101
选择排序的效率:
数据交换次数从O(N^2)变成了O(N),但是比较次数还是O(N^2),但是相比冒泡排序效率肯定更好的,因为交换次数少得多了
插入排序:
大多数情况下,插入排序是这三种排序算法中效率最好的,一般情况下,比冒泡排序快一倍,比选择排序也要快一点,但实现方面也要更麻烦
步骤:
1、把数组分为有序和无序两部分,默认array[0]为有序,其他为无序
2、每次把无序的一个元素插入到有序数组中
3、索引后移,知道所有的元素都变有序
图例:

代码实现:
public static int[] sort(int[] array) {
int i, j;
for (i = 1; i < array.length; i++) { //循环比较的次数,默认从1开始
int temp = array[i]; //先保存要插入的元素
j = i;
while (j > 0 && temp < array[j-1]) { //要插入的元素小于之前的元素,循环直到temp找到要插入的位置
array[j] = array[j-1]; //将之前的元素后移一位
j--; //索引前移一位
}
array[j] = temp; //把temp插入到要插入的位置,也就是第一个大于temp的元素的后面
}
return array;
}
public static void display(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
public static void main(String[] args) {
int[] array = new int[]{77, 99, 33, 44 ,55, 11, 9, 101, 2};
System.out.print("排序前:");
display(array);
sort(array);
System.out.print("\r\n排序后:");
display(array);
}
输出结果:
排序前:77 99 33 44 55 11 9 101 2
排序后:2 9 11 33 44 55 77 99 101
插入排序的特点:
比较次数:1+2+3+...+N-1=N*(N-1)/2
每一轮排序发现插入点之前,平均只有全体数据项的一半进行比较,所以是N*(N-1)/4
复制的次数和比较的次数几乎相同。然而,复制和交换的效率是不同的,所以,插入算法比比冒泡排序快一倍,比选择排序也要快一点
对于有序或基本有序的数据来说,插入排序的效率很好,因为while循环总是false,只是外层的循环而已,时间复杂度O(N)
如果是逆序数据,效率和冒泡排序差不多
内容参考:<Java数据结构和算法>
未完待续。。。
Java数据结构和算法(三)--三大排序--冒泡、选择、插入排序的更多相关文章
- Java数据结构与算法(2) - ch03排序(冒泡、插入和选择排序)
排序需要掌握的有冒泡排序,插入排序和选择排序.时间为O(N*N). 冒泡排序: 外层循环从后往前,内存循环从前往后到外层循环,相邻数组项两两比较,将较大的值后移. 插入排序: 从排序过程的中间开始(程 ...
- Java数据结构和算法(五)--希尔排序和快速排序
在前面复习了三个简单排序Java数据结构和算法(三)--三大排序--冒泡.选择.插入排序,属于算法的基础,但是效率是偏低的,所以现在 学习高级排序 插入排序存在的问题: 插入排序在逻辑把数据分为两部分 ...
- JAVA数据结构和算法 3-简单排序
排序中的两种基本操作是比较和交换.在插入排序中还有移动. 冒泡排序:两两比较相邻元素,如果较大数位于较小数前面,则交换: 每一趟遍历将一个最大的数移到序列末尾,共遍历N-1趟. 如果执行完一趟之后没有 ...
- 【Java数据结构与算法】简单排序、二分查找和异或运算
简单排序 选择排序 概念 首先,找到数组中最小的那个元素,其次,把它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换).再次,在剩下的元素中找到最小的元素,将它与数组的第二个 ...
- Java数据结构和算法(二)--队列
上一篇文章写了栈的相关知识,而本文会讲一下队列 队列是一种特殊的线性表,在尾部插入(入队Enqueue),从头部删除(出队Dequeue),和栈的特性相反,存取数据特点是:FIFO Java中queu ...
- Java数据结构和算法(三):常用排序算法与经典题型
常用的八种排序算法 1.直接插入排序 我们经常会到这样一类排序问题:把新的数据插入到已经排好的数据列中.将第一个数和第二个数排序,然后构成一个有序序列将第三个数插入进去,构成一个新的有序序列.对第四个 ...
- Java数据结构和算法(九)——高级排序
春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大 ...
- Java数据结构和算法 - 高级排序
希尔排序 Q: 什么是希尔排序? A: 希尔排序因计算机科学家Donald L.Shell而得名,他在1959年发现了希尔排序算法. A: 希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插 ...
- Java数据结构和算法 - 简单排序
Q: 冒泡排序? A: 1) 比较相邻的元素.如果第一个比第二个大,就交换它们两个; 2) 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数; 3) 针 ...
随机推荐
- curl测试dns解析时间及tcp连接时间
1.用Linux下的curl命令测量网络请求(分号是分隔符,可以是其他符号): curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer ...
- vim中编辑了代码 但是提示can not write的解决办法和代码对齐办法
方式1: 1 :w /tmp/xxxx(如果是c文件就.c拉) 保存在/tmp下面 2 从tmp中复制到有权限的目录下面 cp /tmp xxxx ./(当前目录) 方式2::w !sudo tee ...
- C++ STL自学总结,仅供参考
本文内容,为博主在网上看到资料总结整合而来 一.stl格式简介 .stl文件是在计算机图形应用系统,来表示封闭的面或者体,用来表示三角形网格的一种文件格式.为STereo Lithography的缩写 ...
- C++经典面试题库 附带参考答案
1. 面向对象的程序设计思想是什么? 答:把数据结构和对数据结构进行操作的方法封装形成一个个的对象. 2. 什么是类? 答:把一些具有共性的对象归类后形成一个集合,也就是所谓的类. 3. ...
- 洛谷P3825 [NOI2017]游戏(2-SAT)
传送门 果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕…… 先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i' ...
- Vue 基础指令学习
学习Vue的一些总结,第一次写博客,文笔实在是很差 不过我会不断写的. <template> <!--只能有一个根节点 --> <div> <pre> ...
- 分层图初探 By cellur925
因为最近测试遇到了分层图的题目,所以稍微学了一下==. 这种题目一般是来解决最短路边权有变化/有k条免费路的问题的.他们基本都一般有两种实现方式:dp+最短路/分层图+最短路 当然你如果非要说他们是一 ...
- Codeforces Round #516 Div2 (A~D)By cellur925
比赛传送门 A. Make a triangle! 题目大意:给你三根木棒,选出其中一根木棒增加它的长度,使构成三角形,问增加的长度最小是多少. 思路:签到题,根据样例/三角形性质不难发现,答案就是最 ...
- LuoguP2700逐个击破【并查集/生成树/正难则反】By cellur925
题目传送门 题目大意:给你一棵树,求把其中k个点相互隔离(不连通)所需要的边权代价. 这题我开始是想要求出把k个点联通的最小代价的,但后来发现还是实现起来比较困难,题解里貌似也没有这种做法,于是就鸽了 ...
- 【bzoj2084】[Poi2010]Antisymmetry
2084: [Poi2010]Antisymmetry Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1205 Solved: 756[Submit ...