冒泡排序,插入排序,选择排序
简要概述
1.冒泡排序
将相邻的元素,第一次必将会便利整个数组。当发现第一个元素大于第二个元素,那就进行交换。逐渐比较循环的次数减少。
2.插入排列
先假定第一个元素是“有顺序的”,之后让他与第二个元素进行比较,如果小于(整个序列按从小到大排列)第一个元素时,则排列在其之前,反之,排在之后。然后将他俩看做一个整体,之后的元素与这个整体中的元素从后往前一次比较,如果小则向前一位继续比较,如果大于则在该位置”插入“。该排列方法排列次数会逐步增加。
3.选择排序
将第一个元素设置为“最小元素”,之后将余下的元素和这个“最小元素”比较,如果小于“最小元素”,则与其调换下标,反之,进行下一元素比较。知乎每次比较上一次选中的“最小元素”固定,然后逐步往下进行。该排列方法会逐渐减少排列次数。
一、三种排序的区别
(1)次数
插入排序的排列次数是逐步增加(但会出现有部分可能次数也很少,但整体趋势是逐步增加)。而冒泡排序和选择排序的排列次数是逐步减少的,因为对于会有一部分“有顺序的”和一部分“没有顺序的”,而“没有顺序的”会根据排列逐步减少。
(2)排列方法
冒泡排序
因为相互之间要交换、比较,逐步将“较小的”元素排列在前端,将“较大的元素”排列在后端。所以第一次所有元素两两比较完成后,最大的元素就会排列在最后。之后每一步会将遍历过的元素中最大的元素排在可动范围内的最后。
选择排序
在第一次所有元素遍历借书后,就将最小元素排列在第一位,之后通过每次对剩下元素“比小”,找出“最小元素”放在之后。
插入排序而插入排序会通过第一次比较(及第一个元素和第二个元素进行大小比较),定下一个有“上限”和“下限”的“范围”,之后将剩余元素依次加入、比较(包括比较“上限”和“下限”)。
二、算法的优化
1.冒泡排序
在冒泡排序的最后两轮时,“无序”的部分其实就只剩下两个元素,而这两个元素在之前的排序中早已变成有序的,但因为循环退出条件是次数大于数组长度,所以算法依旧在执行,我们就可以将循环推出条件变成
for(int i = 0 ; i < array.length - i - 1 ; i ++)
在部分元素进行“交换”的时候,我们发现其实有一些元素原本就比之后元素小,所以虽然循环依旧在进行,但数据并未产生交换,这个时候会浪费资源。随意我们可以在交换的循环中添加一个标记<exchange = true>,表示此时有元素进行交换,所以是无序的。而元素因为没有产生交换时没进入该循环时,标识<exchange = false>,则跳出循环节省资源。
for( int i = 0 ; i < array.length - 1 ; i++ ) {
boolean exchange = false;
System.out.printf( "第%d轮\n" , i + 1 );
for (int j = 0; j < array.length - 1 - i ; j++) {
if (array[j] > array[j + 1]) {
array[j] ^= array[j + 1];
array[j + 1] ^= array[j];
array[j] ^= array[j + 1];
exchange = true ;
}
System.out.println("\t" + Arrays.toString(array));
}
if(exchange){
break;
}
}
2.选择排序
最初的选择排序我们在排列时定义了一个最小值,让该值和其他元素进行比较,最后得出最小值放在第一位。那么根据这个思路,我们可以定义一个最大值,和最小值的思路一样,让他和其他值进行比较,最后将得出的值放在最后。
while (left < right)
{
//定义最小值放在左边,最大值放在右边
int min = left;
int max = right;
for (int i = left; i <= right ; i++)
{
//同时进行最大值最小值比较
if (arr[i] < arr[min])
min = i;
if(arr[i] > arr[max])
max = i;
}
2.插入排序
因为插入排序是将”无序“部分中的元素排列进之前排列好的“有序”部分中,每次对于对该部分的元素一次对比,所以我们可以通过二分法进行对比。
int i, j, temp, m, low, high;
for (i = 1; i < len; i++)
{
temp = arr[i];
low = 0; high = i-1;
while (low <= high)
{
m = (low +high) / 2;
if(arr[m] > temp)
high = m-1;
else
low = m+1;
}
for (j = i-1; j>=high+1; j--)
arr[j+1] = arr[j];
arr[j+1] = temp;
}
三.时间复杂度和空间复杂度
1、冒泡排序的空间复杂度和时间复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)
2、插入排序的空间复杂度和时间复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)
3、选择排序的空间复杂度和时间复杂度
时间复杂度:O((n*(n-1) ) / 2)
空间复杂度:O(1)