排序
1.冒泡排序
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
关于代码实现,两层循环(若N个数排序),外层冒泡轮数(n-1),里层依次比较(n-i),时间复杂度为O(n2)。
public static void sort(int arr[]){
for( int i = 0 ; i < arr.length - 1 ; i++ ){
for(int j = 0;j < arr.length - 1 - i ; j++){
int temp = 0;
if(arr[j] < arr[j + 1]){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
冒泡有一个最大的问题就是这种算法不管不管你有序还是没序,闭着眼睛把你循环比较了再说。
针对这个问题,我们可以设定一个临时遍历来标记该数组是否已经有序,如果有序了就不用遍历了。
public static void sort(int arr[])
{
for( int i = 0;i < arr.length - 1 ; i++ )
{
boolean isSort = true;
for( int j = 0;j < arr.length - 1 - i ; j++ )
{
int temp = 0;
if(arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSort = false;
}
}
if(isSort){
break;
}
}
}
2.选择排序
选择排序的思路是这样的:首先,找到数组中最小的元素,拎出来,将它和数组的第一个元素交换位置,第二步,在剩下的元素中继续寻找最小的元素,拎出来,和数组的第二个元素交换位置,如此循环,直到整个数组排序完成。
public static void sort(int arr[]){
for( int i = 0;i < arr.length ; i++ ){
int min = i;//最小元素的下标
for(int j = i + 1;j < arr.length ; j++ )
{
if(arr[j] < arr[min])
{
min = j;//找最小值
}
}
//交换位置
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
双层循环,时间复杂度和冒泡一模一样,都是O(n2)。
3.插入排序
插入排序的思想和我们打扑克摸牌的时候一样,从牌堆里一张一张摸起来的牌都是乱序的,我们会把摸起来的牌插入到左手中合适的位置,让左手中的牌时刻保持一个有序的状态。
那如果我们不是从牌堆里摸牌,而是左手里面初始化就是一堆乱牌呢? 一样的道理,我们把牌往手的右边挪一挪,把手的左边空出一点位置来,然后在乱牌中抽一张出来,插入到左边,再抽一张出来,插入到左边,再抽一张,插入到左边,每次插入都插入到左边合适的位置,时刻保持左边的牌是有序的,直到右边的牌抽完,则排序完毕。
public static void sort(int[] arr)
{ int n = arr.length; for (int i = 1; i < n; ++i)
{ int value = arr[i]; int j = 0;//插入的位置 for (j = i-1; j >= 0; j--)
{ if (arr[j] > value)
{ arr[j+1] = arr[j];//移动数据(后移一位) }
else
{ break; } } arr[j+1] = value; //插入数据(这次进来的j+1相当于刚才的j) } }
从代码里我们可以看出,如果找到了合适的位置,就不会再进行比较了,就好比牌堆里抽出的一张牌本身就比我手里的牌都小,那么我只需要直接放在末尾就行了,不用一个一个去移动数据腾出位置插入到中间。
最好情况的时间复杂度是 O(n),最坏情况的时间复杂度是 O(n2)
插入排序对于大规模的乱序数组的时候效率是比较慢的,因为它每次只能将数据移动一位
4.希尔排序
插入排序对于大规模的乱序数组的时候效率是比较慢的,因为它每次只能将数据移动一位,
希尔排序为了加快插入的速度,让数据移动的时候可以实现跳跃移动,节省了一部分的时间开支。
void shellSort(int a[], int n) {
for (int step = n / 2; step > 0; step /= 2) {
for (int i = step; i < n; ++i) {
int j, val = a[i];
for (j = n - step; j >= 0 && a[j] > val; j -= step) {
a[j + step] = a[j];
}
a[j + 1] = val;
}
}
}