排序之几大常见算法总结
一、冒泡排序算法
(一)、冒泡排序算法的概念
冒泡排序就是重复“从序列右边开始比较相邻两个数字的大小,再根据结果交换两个数字
的位置”这一操作的算法。在这个过程中,数字会像泡泡一样,慢慢从右往左“浮”到序列的
顶端,所以这个算法才被称为“冒泡排序”。
(二)、冒泡排序算法的流程图
该流程图内容引用自《我的第一本算法书》
(三)、冒泡排序算法的代码示例
private static void bubbleSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
for (int i = 0; i < arr.length; 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;
}
}
}
}
二、插入排序算法
(一)、插入排序算法的概念
插入排序是一种从序列左端开始依次对数据进行排序的算法。在排序过程中,左侧的数据陆续归位,而右侧留下的就是还未被排序的数据。插入排序的思路就是从右侧的未排序区域内取出一个数据,然后将它插入到已排序区域内合适的位置上。
与选择排序一样,当前索引左边的所有元素都是有序的,但它们的最终位置还不确定,为了给更小的元素腾出空间,它们可能会被移动。但是当索引到达数组的右端时,数组排序就完成了。
和选择排序不同的是插入排序所需的时间取决于输入中元素的初始顺序。例如:对一个很大且其中的元素已经有序(或接近有序)的数组进行排序将会比对随机顺序的数组或是逆序数组进行排序要快得多。
(二)、插入排序算法的流程图
该流程图内容引用自《我的第一本算法书》
(三)、插入排序算法的代码示例
private static void insertSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
int j;
for (int i = 1; i < arr.length; i++) {
j = i - 1;
int insertNode = arr[i];
while (j >= 0 && arr[j] > insertNode) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = insertNode;
}
}
三、选择排序算法
(一)、选择排序算法的概念
选择排序就是重复“从待排序的数据中寻找最小值,将其与序列最左边的数字进行交换。”这一操作的算法。在序列中寻找最小值时使用的是线性查找。
选择排序的内循环知识再比较当前元素与目前已知的最小元素(以及将当前索引加1和检查是否代码越界)。交换元素的代码写再内循环之外,每次交换都能排定一个元素,因此交换的总次数是N。
所以算法的时间效率取决于比较的次数。
选择排序有两个很鲜明的特点:
1、运行时间与输入无关。为了找出最小的元素而扫描一遍数组并不能为下一遍扫描提供扫描信息。这种性质在某些情况下是缺点,因为使用选择排序的人可能会惊讶的发现,一个已经有序的数组或是主键全部相等的数组和一个元素随机排列的数组所用的排序时间是一样长。其他的算法会更善于利用输入的初始状态。
2、数据移动是最少的。每次交换都会改变两个数组元素的值,因此选择排序用了N次交换——交换次数和数组的大小是线性关系。(其他大部分的增长数量级都是线性对数或是平方级别)
(二)、选择排序算法的流程图
该流程图内容引用自《我的第一本算法书》
(三)、选择排序算法的代码示例
private static void selectSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
int pos;
for (int i = 0; i < arr.length; i++) {
pos = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[pos]) {
pos = j;
}
}
if (pos != i) {
int temp = arr[i];
arr[i] = arr[pos];
arr[pos] = temp;
}
}
}
四、归并排序算法
(一)、归并排序算法的概念
归并排序算法会把序列分成长度相同的两个子序列,当无法继续往下分时(也就是每个子
序列中只有一个数据时),就对子序列进行归并。归并指的是把两个排好序的子序列合并成一个
有序序列。该操作会一直重复执行,直到所有子序列都归并为一个整体为止。
(二)、归并排序算法的流程图
该流程图内容引用自《我的第一本算法书》
(三)、归并排序算法的代码示例
private static void mergeSort(int[] arr) {
int[] temp = new int[arr.length];
mergeSortImpl(arr, 0, arr.length - 1, temp);
}
private static void mergeSortImpl(int[] arr, int start, int end, int[] temp) {
if (start >= end) {
return;
}
int mid = start + (end - start) / 2;
mergeSortImpl(arr, start, mid, temp);
mergeSortImpl(arr, mid + 1, end, temp);
merge(arr, start, mid, end, temp);
}
private static void merge(int[] arr, int start, int mid, int end, int[] temp) {
int left = start;
int right = mid + 1;
int index = start;
while (left <= mid && right <= end) {
if (arr[left] < arr[right]) {
temp[index++] = arr[left++];
} else {
temp[index++] = arr[right++];
}
}
while (left <= mid) {
temp[index++] = arr[left++];
}
while (right <= end) {
temp[index++] = arr[right++];
}
for (index = start; index <= end; index++) {
arr[index] = temp[index];
}
}
五、快速排序算法
(一)、快速排序算法的概念
快速排序算法首先会在序列中随机选择一个基准值(pivot),然后将除了基准值以外的数分
为“比基准值小的数”和“比基准值大的数”这两个类别,再将其排列成以下形式。
[ 比基准值小的数 ] 基准值 [ 比基准值大的数 ]
接着,对两个“[ ]”中的数据进行排序之后,整体的排序便完成了。对“[ ]”里面的数据
进行排序时同样也会使用快速排序。
(二)、快速排序算法的流程图
该流程图内容引用自《我的第一本算法书》
(三)、快速排序算法的代码示例
private static void quickSort(int[] arr) {
sort(arr, 0, arr.length - 1);
}
private static void sort(int[] arr, int start, int end) {
if (start >= end) {
return;
}
int pivot = arr[start];
int left = start;
int right = end;
while (left <= right) {
while (left <= right && arr[left] < pivot) {
left++;
}
while (left <= right && arr[right] > pivot) {
right--;
}
if (left <= right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
sort(arr, start, right);
sort(arr, left, end);
}