插入排序:简单插入排序、希尔排序
交换排序:冒泡排序、快速排序
选择排序:简单选择排序
1.简单插入排序
算法思想:
设输入的待排序的数组为nums[0..n-1],假设nums[0]已排好序,num为哨兵元素
依次将nums[i](i = 1,2,...,n-1)从后往前插入到前面已排好序的子数组nums[0,..,i-1]中的合适位置
算法示意图:
Java实现:
public static void main(String[] args) {
insertSort(new int[]{3,0,4,1,5,7,11});
}
/**
* 插入排序
*/
public static void insertSort(int[] nums) {
int num;
for (int i = 1; i < nums.length; i++) {
num = nums[i - 1]; // 哨兵
if (nums[i] < num) {
num = nums[i];
int j = i - 1;
for (; j >= 0 && num < nums[j]; --j) {
nums[j+1] = nums[j];
}
nums[j+1] = num;
}
}
for (int k = 0; k < nums.length; k++) {
if (k == nums.length - 1) {
System.out.print(nums[k]);
} else {
System.out.print(nums[k]);
System.out.print(",");
}
}
}
运行结果:0,1,3,4,5,7,11
时间复杂度:
最好情况O(n)、平均情况O(n^2)、最坏情况O(n^2)
空间复杂度:
O(1)
是否稳定:
稳定
2.希尔排序(缩小增量排序)
算法思想:
希尔排序是对插入排序进行改进得到的一种排序算法,希尔排序加入了多趟预排序,正是这多趟预排序,让它的时间复杂度降低了不少。
1>选取一个小于n的步长,把表中全部的数据分成个组,所有距离为的倍数的数据放在同一个组,在各组中进行直接插入排序;
2>选取第二个步长 < ,重复上述步骤,直到所取到的 = 1,此时所有的数据已放到同一组中,最后再进行一次直接插入排序。
算法示例图:
Java实现:
public static void main(String[] args) throws InterruptedException {
shellSort(new int[]{3,0,4,1,5,7,11});
}
/**
* 希尔排序
*/
public static void shellSort(int[] nums) {
int num;
for (int dk = nums.length/2; dk >= 1; dk /= 2) {
for (int i = dk; i < nums.length; i++) {
num = nums[i - dk]; // 哨兵
if (nums[i] < num) {
num = nums[i];
int j = i - dk;
for (; j >= 0 && num < nums[j]; j -= dk) {
nums[j+dk] = nums[j];
}
nums[j+dk] = num;
}
}
}
for (int k = 0; k < nums.length; k++) {
if (k == nums.length - 1) {
System.out.print(nums[k]);
} else {
System.out.print(nums[k]);
System.out.print(",");
}
}
}
运行结果:0,1,3,4,5,7,11
时间复杂度:
平均情况O(n^1.3)
空间复杂度:
O(1)
是否稳定:
不稳定
3.冒泡排序
算法思想:
冒泡排序是一种交换排序,它的基本思想是:两两比较相邻的关键字,如果反序则交换,直到没有反序的记录为止。一般都是从最末尾开始比较,逐个向上冒。冒泡的思想重点是相邻之间的比较,可以看出一个循环完毕之后,第一位一定是一个最小的数,但与此同时在中间的过程中,我们同样可以看到相对小的数也会向上移动,最终都会形成有序的序列。
算法示意图:
Java实现:
public static void main(String[] args) {
bubbleSort(new int[]{3,0,4,1,5,7,11});
}
/**
* 冒泡排序
*/
public static void bubbleSort(int[] nums) {
boolean flag = false;
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j+1]) {
int num = nums[j];
nums[j] = nums[j+1];
nums[j+1] = num;
flag = true;
}
}
if (!flag) break;
}
for (int k = 0; k < nums.length; k++) {
if (k == nums.length - 1) {
System.out.print(nums[k]);
} else {
System.out.print(nums[k]);
System.out.print(",");
}
}
}
运行结果:0,1,3,4,5,7,11
时间复杂度:
最好情况O(n)、平均情况O(n^2)、最坏情况O(n^2)
空间复杂度:
O(1)
是否稳定:
稳定
4.快速排序
算法思想:
1>在表中任取某个节点num作为基准值,将数组nums[left,...,right]划分为两个子数组nums[left,...,index-1]和nums[index+1,...,right],其中nums[left,...,index-1]中的每个元素都小于等于num,nums[index+1,...,right]中的每个元素都大于等于num;
2>通过递归调用快速排序,对子数组nums[left,...,index-1]和nums[index+1,...,right]执行上述操作。
算法示例图:
Java实现:
public static void main(String[] args) {
int[] nums = new int[]{3,0,4,1,5,7,11};
quickSort(nums,0,nums.length - 1);
for (int k = 0; k < nums.length; k++) {
if (k == nums.length - 1) {
System.out.print(nums[k]);
} else {
System.out.print(nums[k]);
System.out.print(",");
}
}
}
/**
* 快速排序
*/
public static void quickSort(int[] nums, int left, int right) {
if (left < right) {
int index = partition(nums,left,right);
quickSort(nums, left, index -1);
quickSort(nums, index + 1, right);
}
}
public static int partition(int[] nums, int left, int right) {
int num = nums[left];
while(left < right) {
while(left < right && num <= nums[right]) --right;
nums[left] = nums[right];
while(left < right && num >= nums[left]) ++ left;
nums[right] = nums[left];
}
nums[left] = num;
return left;
}
运行结果:0,1,3,4,5,7,11
时间复杂度:
最好情况O( )、平均情况O()、最坏情况O(n^2)
空间复杂度:
O()
是否稳定:
不稳定
5.简单选择排序
算法思想:
将最小元素找出并放在序列的最前面,在剩下的元素中继续找出最小的元素放在第二个位置上,以此类推,每次选出一个元素,即可确定其在有序序列中的最终位置。
算法示例图:
Java实现:
public static void main(String[] args) {
int[] nums = new int[]{3,0,4,1,5,7,11};
selectSort(nums);
}
/**
* 简单选择排序
*/
public static void selectSort(int[] nums) {
int length = nums.length;
for (int i = 0; i < length - 1; i++) {
int min = i;
for (int j = i + 1; j < length;j++) {
if (nums[min] > nums[j]) {
min = j;
}
}
if (min != i) {
int flag = nums[min];
nums[min] = nums[i];
nums[i] = flag;
}
}
for (int k = 0; k < nums.length; k++) {
if (k == nums.length - 1) {
System.out.print(nums[k]);
} else {
System.out.print(nums[k]);
System.out.print(",");
}
}
}
运行结果:0,1,3,4,5,7,11
时间复杂度:
最好情况O(n^2)、平均情况O(n^2)、最坏情况O(n^2)
空间复杂度:
O(1)
是否稳定:
不稳定