以升序为例,两个相邻的数比较大小,如果前面的数比后面的数大,那么交换位置。双重for循环,外层循环控制轮数,内层循环控制每轮比较的次数,每轮比较会将该轮最大数交换到最后面。
代码:
public class BubbleSort { public static void main(String[] args) { int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}; BubbleSort(arr); System.out.println(Arrays.toString(arr)); } public static void BubbleSort(int []arr) { //外层循环控制轮数 for(int i=1;i<=arr.length-1;i++) { //内层循环控制每轮比较的次数 for(int j=1;j<=arr.length-i;j++) { if(arr[j-1]>arr[j]) { //借助中间变量交换两个位置上的值 int temp = arr[j-1]; arr[j-1]= arr[j]; arr[j]=temp; } } } } }
动态演示:
以升序为例,在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
代码:
public class SelectionSort { private void mian() { int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}; SelectionSort(arr); System.out.println(Arrays.toString(arr)); } private void SelectionSort(int[] arr) { for(int i =0;i<arr.length-1;i++) { int minIndex = i; for(int j=i;j<arr.length-1;j++) { if(arr[minIndex]>arr[j]) { minIndex = j; //记下目前找到的最小值所在的位置 } } //在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换 if (minIndex != i){ int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } } }
动态演示;
代码:
public class InsertSort { public static void main(String[] args) { int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}; insertionSort(arr); System.out.println(Arrays.toString(arr)); } private static void insertionSort(int []arr){ for(int i=1; i<arr.length; i++){ int preIndex = i-1; int current = arr[i]; while(preIndex>=0 && arr[preIndex]>current){ arr[preIndex+1]=arr[preIndex]; preIndex--; } arr[preIndex+1]=current; } } }
动态演示:
步骤为:
- 从数列中挑出一个元素,称为"基准"(pivot),
- 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
代码:
public class QuickSort { public static void main(String[] args) { int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}; quickSort(arr,0,arr.length-1); System.out.println(Arrays.toString(arr)); } private static void quickSort(int[] arr, int low, int high) { if (low < high) { // 找寻基准数据的正确索引 int index = getIndex(arr, low, high); // 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序 quickSort(arr, 0, index - 1); quickSort(arr, index + 1, high); } } private static int getIndex(int[] arr, int low, int high) { // 基准数据 int tmp = arr[low]; while (low < high) { // 当队尾的元素大于等于基准数据时,向前挪动high指针 while (low < high && arr[high] >= tmp) { high--; } // 如果队尾元素小于tmp了,需要将其赋值给low arr[low] = arr[high]; // 当队首元素小于等于tmp时,向前挪动low指针 while (low < high && arr[low] <= tmp) { low++; } // 当队首元素大于tmp时,需要将其赋值给high arr[high] = arr[low]; } // 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置 // 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low] arr[low] = tmp; return low; // 返回tmp的正确位置 } }
动态演示:
借用下啊哈算法的图:
i和j分别为左哨兵和右哨兵,这里枢纽元定为6,然后分别从左往右(i++)和右往左(j--)开始遍历
左哨兵查找比6大的元素,右哨兵查找比6小的元素
第一次交换结果
第二次交换结果
相遇后直接与枢纽元交换
然后再递归排序就行
原文:https://www.cnblogs.com/gshao/p/10372326.html