冒泡排序
package 冒泡排序;
/**
* 时间复杂度 : O(n2)
* 空间复杂度 : O(1)
* 稳定排序
* */
public class BubbleSort {
public static void commonSort(int[] nums) {
for (int i = 0; i < nums.length; i++) {
for (int j = nums.length-1; j > i; j--) {
//前者大于后者
//相邻的进行比较
if (nums[j] >= nums[j-1]) {
int tmp = nums[j];
nums[j] = nums[j-1];
nums[j-1] = tmp;
}
}
}
}
// 优化
public static void goodSort(int[] nums) {
Boolean flag = true;
for (int i = 0; i < nums.length && flag; i++) {
flag = false;
for (int j = nums.length-1; j > i; j--) {
// 前者大于后者
// 相邻的进行比较
if (nums[j] >= nums[j-1]) {
int tmp = nums[j];
nums[j] = nums[j-1];
nums[j-1] = tmp;
flag = true;
}
}
}
}
public static void main(String[] args) {
int[] nums = {1,2,3,8,7,6,4};
commonSort(nums);
//goodSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
堆排序
package 堆排序;
public class HeapSort {
public static void commonSort(int[] nums) {
// 1. 建堆
createHeap(nums);
// 2. 调整堆
int size = nums.length - 1;
for (int i = 0; i < nums.length; i++) {
int tmp = nums[size];
nums[size] = nums[0];
nums[0] = tmp;
size--;
shiftDown(nums, size, 0);
}
}
private static void createHeap(int[] nums) {
// 最后一个非叶子结点开始建堆
for (int i = nums.length/2 - 1; i >= 0; i--) {
shiftDown(nums, nums.length, i);
}
}
private static void shiftDown(int[] nums, int length, int i) {
// 父亲结点
int parent = i;
// 获取child
int child = (parent * 2) + 1;
// 循环向下调整
while (child < length) {
// 判断那个更小 与更小的交换
if (child + 1 < nums.length && nums[child + 1] < nums[child]) {
child = child + 1;
}
// 将小的向上调整
// 大的向下调整
if(nums[child] < nums[parent]) {
int tmp = nums[child];
nums[child] = nums[parent];
nums[parent] = tmp;
} else {
break;
}
parent = child;
child = (parent * 2) + 1;
}
}
public static void main(String[] args) {
int[] nums = {7,3,4,1,5,8,9};
commonSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
希尔排序
package 希尔排序;
/**
* 时间复杂度 最好 O(n) 最坏O(n2) 平均O(n 1.3)
* 空间复杂度 O(1)
* 不稳定排序
* */
public class ShellSort {
public static void commonSort(int[] nums) {
int gap = nums.length;
while (gap > 1) {
helpSort(nums, gap);
gap = gap / 3;
}
helpSort(nums, 1);
}
private static void helpSort(int[] nums, int gap) {
for (int i = 1; i < nums.length; i++) {
int x = nums[i];
int c = i - gap;
for (; c >= 0 && nums[c] > x ; c -= gap) {
nums[c + gap] = nums[c];
}
nums[c + gap] = x;
}
}
public static void main(String[] args) {
int[] nums = {1,2,3,8,7,6,4};
commonSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
归并排序
package 归并排序;
/**
* 时间复杂度 O(nlogn)
* 空间复杂度 O(n)
* 稳定排序
* */
public class mergeSort {
public static void commonSort(int[] nums) {
helpSort(nums, 0, nums.length);
// 传进去的是一个左闭右开的数组
}
private static void helpSort(int[] nums, int start, int end) {
if(start >= end - 1) {
return;
}
int mid = (end + start) / 2;
// 传进去的是一个左闭右开的数组
helpSort(nums, start, mid);
helpSort(nums, mid, end);
merge(nums, start, mid, end);
}
// 开始 归并排序
private static void merge(int[] nums, int start, int mid, int end) {
int low = start;
int mid2 = mid;
int length = end - start;
int[] array = new int[length];
int k = 0;
//
while (low < mid && mid2 < end) {
if ( nums[low] <= nums[mid2]) {
array[k] = nums[low];
k++;
low++;
} else {
array[k] = nums[mid2];
mid2++;
k++;
}
}
while (low < mid) {
array[k] = nums[low];
k++;
low++;
}
while (mid2 < end) {
array[k] = nums[mid2];
mid2++;
k++;
}
// 将原来的数组写回去
// 写回去的时候一定加上start 并且长度是小于我们当前新建的归并数据
for (int i = 0; i < length; i++) {
nums[i + start] = array[i];
}
}
public static void main(String[] args) {
int[] nums = {1,2,3,8,7,6,4};
commonSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
快排
package 快排;
/**
* 时间复杂度 最坏O(n2) 平均 O(nlogn)
* 空间复杂度 O(Logn) O(n)
* 不稳定排序 12344 可能会改变两个数字的相对顺序
* */
public class QuickSort {
public static void commonSort(int nums[]) {
int len = nums.length;
helpSort(nums, 0, len-1);
}
private static void helpSort(int[] nums, int left, int right) {
if (left >= right) {
return;
}
// 通过 partition 排序
// 然后 进行获取partition之后的基准值
// 这个基准值就是从左边 到右边遍历
int index = partition(nums, left, right);
// 每一次的partition遍历 都会分开两个数组
helpSort(nums, left, index);
helpSort(nums, index + 1, right);
}
private static int partition(int[] nums, int start, int end) {
int value = nums[start];
int left = start;
int right = end;
while (left < right) {
// 必须先从后面遍历比较
while ( (left < right) && nums[right] >= value) {
right--;
}
// 然后再从前面进行遍历比较
// 然后才可以让获得的基准值是
while ( (left < right) && nums[left] <= value) {
left++;
}
// 左右两边 进行交换
swap(nums, left, right);
}
// left 和 right 相遇了
swap(nums, left, start);
return left;
}
private static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public static void main(String[] args) {
int[] nums = {1,2,3,8,7,6,4};
commonSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
直接插入排序
package 直接插入排序;
/**
* 时间复杂度 最好O(n) 最坏O(n2)
* 空间复杂度 O(1)
* 稳定
* 不会改变两个数字的相对顺序
* */
public class InsertSort {
// 工作原理就是设置有序区间 然后逐个比较
// 比较之后扩大有序区间
public static void commonSort(int nums[]) {
/**
* 7, 3, 2, 4, 6, 8
* 第一次循环 x=nums[1]=3 c=0
* nums[c]=7 > 3
* nums[c+1]=nums[1]=nums[c]=7
* for循环结束 c-- c=-1
* nums[0]=3
* 得到 3,7,2,4,6,8
* 第二次循环 x=nums[2]=2 c=1
* nums[c]=7 > 2
* */
for (int i = 1; i < nums.length; i++) {
// 第一次开始的时候设置有序区间
// 每一次的比较都是让后一个和前面的有序区间顺序比较
int x = nums[i]; // 有序区间接下来的一个
int c = i -1; // 有序区间最后一个
// 从有序区间的最后后面开始比较 如果比有序区间的最后一个大 直接赋值
// 如果小的话 进入有序区间 依次进行比较 进行交换
for (; c >= 0 && nums[c] > x; c--) {
nums[c + 1] = nums[c];
}
nums[c + 1] = x;
}
for(int i = 1; i < nums.length; i++) {
int x = nums[i]; // 第二个
int c = i-1; // 第一个
for (; c >= 0 && nums[i] > x ; c--) {
nums[c+1] = nums[c];
}
nums[c+1] = x;
}
}
public static void main(String[] args) {
int[] nums = {1,2,3,8,7,6,4};
commonSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
选择排序
package 选择排序;
/**
* 时间复杂度 O(n2)
* 空间复杂度 O(1)
* 不稳定排序
* */
public class SelectSort {
/**
* 第一个数 和 后面的依次比较 选择出最小的数
* 然后最小的数和第一个数交换
* 然后开始第二个数和后面的数开始比较
* */
public static void commonSort(int[] nums) {
for (int i = 0; i < nums.length; i++) {
int max = i;
// int min = i;
for (int j = i + 1; j < nums.length; j++) {
// if(nums[j] < nums[min]) {
// min = j;
// }
// 开始顺序比较 比较那个是剩下的里面最大的
// 并且取得下面得下标
if (nums[j] > nums[max]) {
max = j;
}
}
// 最终得到的max值不是i的话
// 就证明要将max下标的数和i下标的数进行交换
if(max != i) {
int tmp = nums[i];
nums[i] = nums[max];
nums[max] = tmp;
}
}
}
public static void main(String[] args) {
int[] nums = {1,2,3,8,7,6,4};
commonSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
}
}
稳定排序和不稳定排序
稳定排序 : 冒泡排序 归并排序 插入排序
不稳定排序:希尔排序 快排 选择排序 堆排