冒泡排序:
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
选择排序:
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
插入排序:
插入排序(Insertion sort)是一种简单直观且稳定的排序算法。如果有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
package com.yzy.algorithms;
import java.util.Arrays;
/**
* 冒泡、选择、插入排序
*/
public class TestSort {
public static void main(String[] args) {
int[] arr = { 12, 56, 4, 77, 2 };
// BubbleSort(arr);
// SelectSort(arr);
// InsertSort(arr);
InsertSort2(arr);
System.out.println(Arrays.toString(arr));
}
// 这里先写一个交换的方法,不能只传a,b这样调用会随着方法的结束而结束没有效,只有引用类型才行,所以传入一个数组
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
// 冒泡排序
public static void BubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {// 外层循环控制轮数
boolean flag = true;// 这里作了一下优化,如果执行下面的语句没有交换的话,就说明排序已完成没有必要在进行下去了
for (int j = 0; j < arr.length - 1 - i; j++) {// 每排序一次下一轮会少排一次,所以这里是arr.length - 1 - i
if (arr[j] > arr[j + 1]) {// 从小到大
swap(arr, j, j + 1);// 交换
flag = false;// 标准
}
}
if (flag)// 为true就说明排序完成直接跳出
break;
}
}
// 选择排序
public static void SelectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {// 外层循环控制轮数
int min = i;// 记录最小下标,这样每次排序只用交换一次,小优化
for (int j = i + 1; j < arr.length; j++) {// 这里j=i+1是因为第一个数第一次比的时候是与第二个数比,所以要遍历完的话长度相应的要加1
if (arr[min] > arr[j])// 比最小值还小说明最小值要换了
min = j;// 这里是给下标不是给值
}
if (i != min)// 如果i已经等于最小值了就没必要交换了,小优化
swap(arr, i, min);
}
}
// 插入排序
public static void InsertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {// 外层循环控制轮数,从有序数列与无序数列的第一个数开始,第一轮就是arr[1];
for (int j = i; j > 0; j--) {// 插入排序是从后往前所以使用降序循环更方便
if (arr[j] < arr[j - 1])// 如果前面的比后面大就插进来
swap(arr, j, j - 1);
}
}
}
// 插入排序优化
public static void InsertSort2(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];// 这里将有序与无序列的分割的第一个值赋值给临时变量
int j = i;// 这里把j拿出来是因为后面要将arr[j]里面的值覆盖,不然它只在for循环里面有用
for (; j > 0 && temp < arr[j - 1]; j--) {// 插入是从后往前遍历,所以是倒着来,这里优化了一下,能进循环的一定是比临时变量大的
arr[j] = arr[j - 1];// 将大的往后挪
}
arr[j] = temp;// 将临时变量的值赋值给arr[j]
}
}
}