冒泡排序
思想
冒泡排序,又称下沉排序,其大致思路为:
在一个整数序列中,两两进行比较,若前者大于后者,则两者交换位置,若后者大于前者,则保持不变继续进行比较。在进行完一次冒泡后,则会将最大元素放至序列最后。序列中有多少数据,就需要进行多少趟冒泡。
示例如下
代码
代码实现:
public static void bubbleSort(int[] array){
//参数合法性判断
if(array == null||array.length==0){
return;
}
//时间复杂度 不包含系数 O(n^2)
//空间复杂度 O(1)
//稳定性 1 2 2' 0 5 -》0 1 2 2' 5 稳定
//冒泡的趟数
for(int i = 0;i<= array.length-1;i++){
//一趟冒泡的过程
for(int j=0;j< array.length-i-1;j++){ //每次比较的数据都比上一躺少一个
if(array[j]>array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}
我们观察到以上代码可以实现冒泡排序,但是如果进行完几次排序后,剩下的数组本来就有序,导致整个序列已经有序,此时代码仍会执行,就会浪费时间和空间,为了解决这个问题,我们可以定义一个布尔类型变量,初始化为false,若执行了交换位置操作再赋值为true,就可以在数组有序时停止循环。优化后代码如下:
public static void optimizedbubbleSort(int[] array){
//参数合法性判断
if(array == null||array.length==0){
return;
}
//时间复杂度 不包含系数 O(n^2)
//空间复杂度 O(1)
//稳定性 1 2 2' 0 5 -》0 1 2 2' 5 稳定
//冒泡的趟数
boolean nextSort = true;
for(int i = 0;i<= array.length-1&&nextSort;i++){
//一趟冒泡的过程
nextSort = false;
for(int j=0;j< array.length-i-1;j++){
if(array[j]>array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
nextSort = true;
}
}
}
}
选择排序
思想
选择排序,选择序列中最小的元素与第一个元素进行交换。
它的工作原理是:第一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
代码
代码如下
public static void SelectSort(int[] array){
if(array == null||array.length==0){
return;
}
//时间复杂度O(n^2) 空间复杂度O(1)
//稳定性:不稳定
for(int i = 0;i< array.length;i++){
//i表示待排序列的第一个值
int minIndex = i;
for(int j = i+1;j< array.length;j++){
if(array[j]<array[minIndex]){
minIndex = j;
}
}
//minIndex保存的最小元素下标
if(minIndex!=i){
int tmp = array[i];
array[i] = array[minIndex];
array[minIndex] = tmp;
}
}
}
这里我们可以对算法进行优化,在每次将最小元素与第一位进行交换时,也将最大元素与最后一位进行交换。优化后的选择排序如下:
public static void optimizedSelectSort(int[] array){
if(array == null|| array.length == 0){
return;
}
for(int i=0;i<array.length/2;i++){
int minIndex = i;
int maxIndex = i;
for (int j=i+1;j<=array.length-1-i;j++){
if(array[j]<array[minIndex]){
minIndex = j;
continue;
}
if(array[j]>array[maxIndex]){
maxIndex = j;
}
}
//minIndex指向的最小值与第一个值进行交换
int tmp = array[minIndex];
array[minIndex] = array[i];
array[i] = tmp;
//
if(maxIndex == i){
maxIndex = minIndex;
}
//maxIndex指向的最大值与最后一个值交换
tmp = array[maxIndex];
array[maxIndex] = array[array.length-i-1];
array[array.length-i-1]=tmp;
}
}
直接插入排序
思想
直接插入排序,每一趟将一个待排序的记录,按其关键字的大小插入到已经排好序的一组记录的适当位置上,直到所有待排序记录全部插入为止。我们可以类比打扑克,拿到一张牌,与手中牌从前往后进行比较找到比前大的,插入到他前面。
代码
代码如下:
public static void insertSort(int[] array){
if (array == null|| array.length==0){
return;
}
//时间复杂度O(N^2) 空间复杂度O(1)
//稳定性:稳定
for (int i= 0;i< array.length;i++){
int tmp = array[i];
int j=0;
for(j=0;j<=i-1;j++){
if(array[j]>tmp){
break;
}
}
//挪动j~array.length-1的牌往后一位
for (int k = i-1;k>=j;k--){
array[k+1]=array[k];
}
array[j] = tmp;
}
}