基础排序——冒泡排序、选择排序、插入排序的讲解、代码实现
选择排序:
这里有个视频非常清晰,用舞蹈的形式展现排序的过程。先拿出一个元素,通常是第一个元素arr[0]开始,与数组中他之后的紧挨着(+1)的那个元素开始挨个进行比较,如果遇到比arr[0] 大的,就交换元素,交换后,由新的元素(即新的值)按照当前的比较顺序比继续进行后面的较、交换操作。
然后第二个元素 、第三个元素 依次进行比较,交换。
注意:
- 第一个元素比较交换后(即第一次外层循环后),能确定出最小的元素,并且已经被交换到数组的第一个元素;
- 第二个元素比较交换后(即第一次外层循环后),能确定出倒数第二小的元素,并且已被交换到数组的第二个元素。
- 由于排出n-1个元素,最后一个就不需要排序了,所以外层的循环次数是arr.length-1
代码
//准确写法 注意两次循环的长度 public static void selectSort(int[] arr) { int temp = 0; int changeCount = 0; for (int i = 0; i < arr.length-1; i++) { for (int j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; changeCount++; } } } for (int i : arr) { System.out.print(i); } System.out.println("交换次数"+changeCount); }
冒泡排序:
就像石头沉入水底,石头上的灰尘会向上冒,直到浮出水面。每次都从第一个元素开始(比较次数很多),逐个与其他元素进行比较,如果大就交换元素(),所以每一次比较(每一次外层循环)就会确定一个最大值到数组最末尾,这样内层循环每次需要比较次数就会少一次。
外层循环的意义:每次确定一个最大值,也就决定了内存循环的比较次数
内层循环的意义:根据外层循环的i值(也就是排出了i个元素的序了,所以可以确定接下来的循环需要的比较次数为arr.length-1-i)。
tips:
1.排出N-1个元素,留下的就是最小(或最大)的元素。所以外层循环的次数是arr.length - 1
2.外层每排好一个元素,内层需要比较的次数就少一次,所以内层循环的次数是arr.length - 1 - i
代码
// 冒泡排序 public static int[] maoPao(int[] ary2) { int changeCount = 0; for (int i = 0; i < ary2.length - 1; i++) { //每次冒泡一个,最后一个不需要冒泡,因此是length-1次 for (int j = 0; j < ary2.length - i - 1; j++) { if (ary2[j] > ary2[j + 1]) { //与自身元素比较,比较次数多,交换次数多。 int temp = ary2[j]; ary2[j] = ary2[j + 1]; ary2[j + 1] = temp; changeCount++; } } } System.out.println(changeCount); return ary2; }
插入排序
拿一个元素(通常是第二个元素)插到一个元素之后,与其前所有元素挨个进行比较,若比其大就交换元素,直到前面没有比他大的。若果上来就比其小,就不交换,顺序是正确的。可以保证后面比较时,插入的位置前面的元素都是排好序的。也就是从前向后排序。
代码
public static void main(String[] args) { int[] arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = (int)(Math.random() * 10); System.out.print(arr[i] + ","); } for (int i = 1; i < arr.length; i++) {//从第二个元素向前插入 int index = i; int temp = arr[i]; while(index > 0 && arr[index -1] > temp){ arr[index] = arr[index - 1]; index--; } arr[index] = temp; } System.out.println(); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]+ ",") ; } }