冒泡排序
介绍:
在冒泡排序中,只有当两个元素不满足条件的时候才会需要交换,所以只有后一个元素大于前一个元素时才进行交换,这时的冒泡排序是一个稳定的排序算法。
步骤:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
本质上是一个数组经过每轮将最大/第二大/第三大(以此类推)逐个将数放在最后/次后的算法
这里将{5,1,2,4,9,3}通过第一次排序后,将最大的9通过换位放在最后,同时一个数在n个数中比较大小,不需要和自身进行比较,因此只需要n-1次,在数组中也就是array.length-1次
在内部循环中,也就是第二轮循环寻找第二大数值时,最大的数与第二大的数字在第一轮已经进行过比较,所以可以省略比较步骤
当i=2时,也就是外层循环进行第三轮比较时,(第三大的数字),第三大数字与第二大(5和4)在上一轮已经进行过比较,因此省略多余步骤,(5和9依然不需要再次比较)
以此类推,可以发现重复的步骤与i的值相同,因此我们可以得出内部循环的结束条件为:array.length-1-i
程序中执行:
public static void main(String[] args) { int []array = {5,1,2,4,9,3}; for (int i = 0; i < array.length-1; i++) { for (int j = 0; j < array.length-1-i; j++) { if(array[j]>array[j+1]){ int tem = array[j]; array[j] = array[j+1]; array[j+1] = tem; } } } System.out.println(Arrays.toString(array)); }
选择排序
步骤:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
简单来说就是找到最小数字的索引,与第一个数字交换,然后从第二个开始找到最小的数(此时最小的数是第二小的数,因为最大的已经排到了它的前面)
在外循环中,执行的次数是array.lenth-1,因为从数组第二位开始与自身进行比较
内循环开始执行,依次与3以后的数字进行比较,直到有比3还小的数时,记录索引min
否则继续遍后面的数
当i=1时,进行第二位数字的寻找,与第一遍不同的是.此时无需再比较数组i=0,(也就是当前索引以前的数字,因为前面的数字当前已经是最小的数).也就是j只需要从i+1开始执行
最终
程序中执行
插入排序
步骤:
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
简单说就是从数组第二个开始默认前面已经拍好序列,记录这一位数组的值,当该数大于前面数时插入,小于前面数时,将前面放索引+1也就是后移,直到该数大于前一位时插入,依次往后
当i=1的时候,记录前一位的索引为preIndex,可以发现5大于3,此时直接插入,默认前面已经排好序(前面是3),
i=2的时候,此时preIndex的值右移变为1,然后此时需要丛2开始进行插入,当2与5比较时候,小于5,因此5的索引此时后移(不必担心会改变数组原有的值,此时后移,占用的是原来为2索引为2的位置)
之后原来为5的数组的值变成2,preIndex--;(每当数组的值后移的时候-1),此时再次与preIndex的值比较,依然小于前一个数,于是再次preIndex--;并且将3的索引后移;但是此时preIndex为-1,说明以及到达数组边界,因此将2放到该位置变成{2,3,5,8,9,6}
i=3,i=4的时候,分别插入8,9;发现都大于preIndex所对应数,因此直接插入
i=5时,6小于9;因此将6向前继续比较,9和8依次后移,preIndex分别为4,3;最终得到排序结果
程序中执行
改变while中变量current与array[preIndex]大小关系可以改为升序或者降序;
当前一个值大于当前值时候,执行循环和小于时执行循环这两种情况;(循环内的操作是将前一个值后移,也就是说换句话来说会将较大(较小)的值插入在后面)
多维数组中的三种排序:
在多维数组中对多个数组某一索引进行排序
假设有这样一组二维数组
int[][] scores = { {90, 89, 78}, {59, 40, 100}, {100, 99, 80}, {80, 61, 61}, {60, 100, 99} };
整体排序:
1.冒泡
如何用冒泡排序对数组中每一个数组进行排序?
循环嵌套可以最基本的完成
i为遍历每一个数组的循环,j是对数组每一个数的排序,k是每个数进行比较的次数
//遍历每一个数组 for (int i = 0; i < scores.length; i++) { //进行每个数组内排序(次数为基本的一维数组排序) for (int j = 0; j < scores[i].length - 1; j++) { for (int k = 0; k < scores[i].length-1-j ; k++) { if (scores[i][k] < scores[i][k + 1]) { int tem = scores[i][k]; scores[i][k] = scores[i][k + 1]; scores[i][k + 1] = tem; } } } }
得到结果
2.选择排序
for (int i = 0; i < scores.length; i++) { for (int j = 0; j < scores[i].length-1; j++) { int min =j; for (int k = j+1; k < scores[i].length; k++) { if(scores[i][k]<scores[i][min]){ min = k;//记录最小值索引 } } int tem = scores[i][j]; scores[i][j] = scores[i][min]; scores[i][min] = tem; } }
组内某一元素进行排序
首先有这样三组数组
String[] names = {"安琪拉", "王昭君", "蔡文姬", "妲己", "张良"}; String[] courses = {"C++", "JAVA", "PYthon"}; int[][] scores = { {90, 89, 78}, {59, 40, 100}, {100, 99, 80}, {80, 61, 61}, {60, 100, 99} }; //以及对列表输出的方法 public static void JAVA(int scores[][], String names[], String courses[]) { for (int i = 0; i < scores.length; i++) { System.out.print(names[i] + " => "); // 输出学生姓名 for (int j = 0; j < scores[i].length; j++) { System.out.print(courses[j] + ":");// 输出课程名称 System.out.print(scores[i][j]); // 输出课程成绩 if (j < scores[i].length - 1) { System.out.print(" , "); } } System.out.println(); } }
1.冒泡排序JAVA成绩
此处两个交换不同点是,成绩是二维数组,而name是一维数组,交换的一个是数组,一个是数组内的元素,这里需要分清楚
以及注意这里j的条件是score.length,因为相当于是把二维数组看成一维数组进行排序,JAVA成绩以外的元素我们不需要关注,也就是说本质上是比较5个Java成绩
for (int i = 0; i < scores.length - 1; i++) { for (int j = 0; j < scores.length - 1 - i; j++) { if (scores[j][1] < scores[j + 1][1]) { //交换数组排序 int []tem = scores[j]; scores[j] = scores[j + 1]; scores[j + 1] = tem; //同时交换另一个数组排序 String nam = names[j]; names[j] = names[j+1]; names[j+1] = nam; } } }
运行结果
2.选择排序
此处与选择排序不同的一点是,交换的是数组,而不是某一个数,原理依旧是把每一个数组看成若干个数
for (int i = 0; i <scores.length; i++) { //最小值 int min =i; for (int j = i+1; j < scores.length; j++) { if(scores[j][2]>scores[min][2]){ min = j; } } int []tem = scores[i]; scores[i] = scores[min]; scores[min] = tem; }
3.插入排序
此处原理不变,唯一改变的是带入数组元素索引,排序依旧是数组之间的排序,至少每个数组看成数字即可
int left = 0; int right = scores.length - 1; for (int i = 1; i < scores.length; i++) { int index = i - 1; int cur = scores[i][0]; while (index >= 0 && cur > scores[index][0]) { scores[index + 1][0] = scores[index][0]; index--; } scores[index + 1][0] = cur; }