一、冒泡排序
1、时间复杂度:
平均:O(n^2)
最坏O(n^2)
最好O(n)
空间O(1)
2、原理:
每次选出一个放最前边(每次选出一个最大的放最后边)
3、代码:
public static void bubbleSort(int[] arr) {
int count = 0;
// 外层循环, 控制要进行多少趟比较, n-1趟
for (int i = 0; i < arr.length - 1; i++) {
// 设置一个标记, 用于表示顺序是否已经排好, 如果已经有序, 后续的循环无须再执行
boolean flag = true;// true表示已经有序
// 内层循环, 用于进行两个数的比较, 前面的数大于后面的数, 则进行交换
for (int j = 0; j < arr.length - i - 1; j++) {
count++;
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
// 进行了交换, 说明还没有排好顺序
flag = false;
}
}
// 判断是由已经有序
if (flag) {
break;
}
}
System.out.println("比较次数:" + count);
}
二、选择排序
1、时间复杂度:
平均:O(n^2)
最坏:O(n^2)
最好:O(n^2)
空间:O(1)
2、原理
假定第一个数最小, 然后循环比较, 记录最小值对应的索引, 然后进行交换
3、代码:
public static void selectSort(int[] arr) {
// 一共要循环几趟
for (int i = 0; i < arr.length - 1; i++) {
// 记录最小值的索引
int minIndex = i;
// 内层循环, 找到最小值对应的索引
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
// 修改最小值对应的索引
minIndex = j;
}
}
if (minIndex != i) {
// 交换
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
三、插入排序
1、时间复杂度:
平均:O(n^2)
最坏:O(n^2)
最好:O(n)
空间:O(1)
2、原理
把数组分成有序的和无序的两部分, 刚开始有序的为第一个数, 无序的为剩下的数 接下来每次在无序的数组中取一个数跟有序部分进行比较找到合适的位置插入进去, 直到所有的数组都有序
3、代码:
public static void insertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
if (arr[i] < arr[i - 1]) {
int temp = arr[i];
int j;
for (j = i - 1; j >= 0; j--) {
if (temp < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
// 将temp插入到指定位置
arr[j + 1] = temp;
}
}
}
四、快速排序
1、时间复杂度:
平均:O(nlog2n)
最坏:O(n^2)
最好:O(nlog2n)
空间:O(nlog2n)
2、原理
通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。
一趟快速排序的具体过程可描述为:从待排序列中任意选取一个记录(通常选取第一个记录)作为基准值,然后将记录中关键字比它小的记录都安置在它的位置之前,将记录中关键字比它大的记录都安置在它的位置之后。这样,以该基准值为分界线,将待排序列分成的两个子序列。
3、代码:
public static void QuickSort(int arr[], int start, int end){
if (start >= end)
return;
int i = start;
int j = end;
// 基准数
int baseval = arr[start];
while (i < j){
// 从右向左找比基准数小的数
while (i < j && arr[j] >= baseval){
j--;
}
if (i < j){
arr[i] = arr[j];
i++;
}
// 从左向右找比基准数大的数
while (i < j && arr[i] < baseval){
i++;
}
if (i < j){
arr[j] = arr[i];
j--;
}
}
// 把基准数放到i的位置
arr[i] = baseval;
// 递归
QuickSort(arr, start, i - 1);
QuickSort(arr, i + 1, end);
}
五、归并排序
1、时间复杂度:
平均:O(nlog2n)
最坏:O(n^2)
最好:O(nlog2n)
空间:O(n )
2、原理
把长度为n的输入序列分成两个长度为n/2的子序列,对这两个子序列分别采用归并排序,将两个排序好的子序列合并成一个最终的排序序列。
3、代码:
public static void MergeSort(int arr[], int start, int end, int * temp){
if (start >= end) return;
int mid = (start + end) / 2;
MergeSort(arr, start, mid, temp);
MergeSort(arr, mid + 1, end, temp);
int length = 0;
int i_start = start;
int i_end = mid;
int j_start = mid + 1;
int j_end = end;
while (i_start <= i_end && j_start <= j_end){
if (arr[i_start] < arr[j_start]){
temp[length] = arr[i_start];
length++;
i_start++;
}
else{
temp[length] = arr[j_start];
length++;
j_start++;
}
}
while (i_start <= i_end){
temp[length] = arr[i_start];
i_start++;
length++;
}
while (j_start <= j_end){
temp[length] = arr[j_start];
length++;
j_start++;
}
for (int i = 0; i < length; i++){
arr[start + i] = temp[i];
}
}