①冒泡排序:
public int[] bubble(int[] nums) {
if (nums.length == 0) {
return nums;
}
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length - i - 1; j++) {
if (nums[j] > nums[j + 1]) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
return nums;
}
冒泡排序:遍历数组,当遇到数据比自身小,则替换数据,做到最大值在数组最后;后续遍历就不用再管末尾数据。
双重遍历,外部遍历整个数组,用于将数组所有元素依次比较、交换位置,内部用于元素进行元素遍历,因为遍历结果会将最大数组放到末尾,所以末尾元素不用再判断(即已经检测过的i)。
平均时间复杂度O(N²)
②选择排序:
public static int[] select(int[] nums) {
if (nums.length == 0) {
return nums;
}
for (int i = 0; i < nums.length; i++) {
int min = i;
for (int j = i; j < nums.length; j++) {
if (nums[j] < nums[min]) {
min = j;
}
}
int temp = nums[min];
nums[min] = nums[i];
nums[i] = temp;
}
return nums;
}
选择排序:记录当前位置数,遍历未排序部分数据,找到最小数与当前位置数据替换。
同样双重遍历,外层用于遍历整个数组进行比较,首先默认记录当前数字为最小值,内层遍历用于查找真正最小值,找到后将下标i数值与最小值替换,即可实现排序。
时间复杂度:O(N²)
③插入排序
public static int[] insert(int[] nums) {
if (nums.length == 0) {
return nums;
}
int current;
for (int i = 0; i < nums.length - 1; i++) {
current = nums[i + 1];
int pre = i;
while (pre >= 0 && current < nums[pre]) {
nums[pre + 1] = nums[pre];
pre--;
}
nums[pre + 1] = current;
}
return nums;
}
插入排序:当前位置为基准值,取出下一值在已排序部分进行遍历,若遍历到的值比取出的值大,则需要将数据向后挪一位(空出新值插入位置),直到遇到值比取出值小,将新值插入。
双重遍历,外部可以看做记录已排序数量,记录当前数据(即新值),pre即排序数据中的最后一位,将新值以此与pre值进行比较,若新值小,则将pre后移一位,pre计数提前一位,若新值大,将该新值插入当前pre+1位置即可。
时间复杂度:O(N²)
④快速排序:
public static void fast(int[] nums, int start, int end) {
if (start >= end) {
return;
}
int i = start;
int j = end;
while (i < j) {
while (i < j && nums[j] >= nums[start]) {
j--;
}
while (i < j && nums[i] <= nums[start]) {
i++;
}
swap(nums, i, j);
}
swap(nums, i, start);
fast(nums, start, i - 1);
fast(nums, i + 1, end);
}
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
快速排序:以数组第一个值为基准值,左右指针分别寻找比基准值大、小的值,都找到后进行调换,知道左右指针相遇,相遇后将基准值挪到相遇位置,至此 基准值左侧都比其小,右侧都大;再对左右两侧进行快速排序即可。
时间复杂度:O(Nlog2N)