排序算法
插入排序
public int[] insertSort(int[] nums) {
// 算法思想主要是对数组的每一个数与前面的数对比将他放置在对的位置
// 从第1个数开始因为第0个数的前面是空的
for (int i = 1; i < nums.length; i++) {
int temp= nums[i];
int j;
// 查看这个数的前面所有数字
for (j = i-1; j >= 0; j--) {
// 如果前面的数字大于自己 那么将这个数字后移
// 一旦出现一个数小于等于自身,那么说明这个数的前面所有数都满足小于等于自身
// 因为此算法的本质就是分段排序 自身的前面所有数字都已经有序
if (temp<nums[j]){
nums[j+1]=nums[j];
}else {
break;
}
}
nums[j+1]=temp;
}
return nums;
}
因为这个算法中,其实自身的前面所有数都已经是有序的了 因此我们只需要找到 最后一个大于等于前面的数的位置即可
在有序数组中,最快找到对应位置的算法就是折半查找(二分查找)
举个例子:
我们需要将low~i-1的所有元素右移,然后low的位置就是空闲的,然后将55放入low的位置
用二分法优化插入排序:
public int[] insertSortBinary(int[] nums) {
for (int i = 1; i < nums.length; i++) {
int temp = nums[i];
// 左边界
int left = 0;
// 右边界
int right = i - 1;
// 从图中我们可以看出当左边界大于有边界时就找到了对应的位置,位置是最后left所指向的位置
while (left > right) {
int mid = (left + right) / 2;
if (nums[mid] > temp) {
right = mid - 1;
} else {
// 让相等的情况走这个语句,这样可以保持稳定性
left = mid + 1;
}
}
for (int j = i - 1; j >= left; j--) {
nums[j+1]=nums[j];
}
nums[left]=temp;
}
return nums;
}
冒泡排序
此算法的本质就是每一轮找到一个最大值放在数组的对应位置
因为他的算法是每两个相邻位置的元素进行比较,让小的在左边大的在右边持续比较直到数组的尾部或是后面已经排序过的位置
如果一趟冒泡都没有发生交换,说明已经有序,不用继续直接返回
public int[] bubbleSort(int[] nums) {
// 用来判断是否有交换
boolean flag = false;
// 这表示需要多少次的循环
// 如果有5位数,执行了四次 那么就说明最大值都已经在队尾 那么只剩一个就不需要排序了
for (int i = 0; i < nums.length-1; 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;
flag = true;
}
}
if (!flag) {
return nums;
}
}
return nums;
}