排序算法之冒泡和快排
冒泡排序:
顾名思义:参与排序的数据就像水中的气泡慢慢浮出水面一样“浮”到数列顶端。
冒泡排序要点:
1、 两层循环,外层循环控制走访数列重复进行的次数,内层循环进行数据的比较、交换,是数据“上浮”。
2、 内层循环是相邻的数据进行比较。
C语言代码实现:
// 冒泡排序 void sort_bubble(int n){ int i,j; for(i=0;i<n-1;i++){ for(j=0;j<n-1-i;j++){ if(arr[j]>arr[j+1]){ // 进行一次交换 exchange(j,j+1); } } } }
代码优化:
通过对核心代码的分析,不难发现,当给我们的数据已经是有序状态时,外层循环仍旧会执行n-1次,内层循环因为数据已经有序,只会进行相邻数据的比较而不进行数据的交换。这个时候我们的外层循环导致我们的程序做了很多的无用功。因此我们需要对外层循环进行优化。
我们已经知道,如果我们的数据已经是有序状态时,程序的内层循环是只进行数据的比较而不进行数据的交换,那么我们可以在内层循环设置一个变量,用来通知外层循环数据是否已经达到有序状态,如果已经有序,则跳出外层循环,否则,继续执行。
优化代码:
// 冒泡排序 void sort_bubble(int n){ int i,j; int m; for(i=0;i<n-1;i++){ m = 1; // 默认数据已经为有序状态 for(j=0;j<n-1-i;j++){ if(arr[j]>arr[j+1]){ // 进行一次交换 exchange(j,j+1); m = 0; // 数据进行了交换,说明数据还没有达到完全有序状态 } } if(m==1){ break; // 如果m=1,说明数据已经为有序状态,跳出外层循环 } } }
快速排序:
快速排序是最常用的一种排序算法,因为速度快,效率高而得名。
快速排序采用的是分治思想。
(分治思想其实就是把一个复杂的问题分解成 与原问题性质相同且相互独立的 若干个可以直接求解的小问题。)
快速排序思路:
在一个给定的数据中,选一个元素作为基准值(这里选择第一个元素),然后先从后往前遍历,找到一个比这个基准值小的元素,把这个元素放到这个基准值的左边,然后再从前往后遍历,找到一个比基准值大的元素,放到这个基准值的右边,直到遍历所有元素。
当我们遍历一遍数据之后,以这个基准值为基点,分成两组数据量小的数组,然后对这两个数组继续执行上述操作。
Java代码:
public class QuickSort { // 快速排序 public void sort_quick(int[] arr, int first, int last) { int start = first; int end = last; int key = arr[first]; if (first >= last) return; int flag = 1; // 是否有序的标记 while (start < end) { while (start < end && arr[end] >= key) end--; if (start < end) { arr[start] = arr[end]; arr[end] = key; start++; flag = 0; } while (start < end && arr[start] <= key) start++; if (start < end) { arr[end] = arr[start]; arr[start] = key; end--; flag = 0; } } arr[end] = key; if(flag == 1){ return; } if (start > first) { sort_quick(arr, first, start - 1); } if (end < last) { sort_quick(arr, end + 1, last); } } }