常见排序算法发时间复杂度
插入排序法
直接插入
基本思想:假设第一个元素已经排好,从第二个元素开始,依此与前面的比较,如果比前面的小,就继续向前比较。直到遇见比前面一个元素大的情况,将元素放置在该位置。从第三个元素开始,继续上述步骤。
public static void insertSort(int [] nums){
for(int i = 1; i < nums.length; i++){
int temp = nums[i];
int j = i - 1;
for(; j >= 0; j--){
if(nums[j] > temp){
nums[j+1] = nums[j];
}else{
break;
}
}
nums[j+1] = temp;
}
}
希尔排序
基本思想:先确定一个间隔,通常取g=n/2。将整个待排序的记录序列以g为间隔分割成为若干子序列分别进行直接插入排序,之后再g=g/2. 再次执行上述操作,直到g=1,再对全体直接插入排序。
public static void shellSort(int [] nums){
int gap = nums.length;
while(gap > 1){
shell(nums,gap);
gap = (gap/3)+1;
}
shell(nums,1);
}
public static void shell(int [] nums, int gap){
for(int i = gap; i < nums.length; i++){
int temp = nums[i];
int j = i - gap;
for(;j >= 0; j = j - gap){
if(nums[j] > temp){
nums[j+gap] = nums[j];
}else{
break;
}
}
nums[j+gap] = temp;
}
}
交换排序
冒泡排序
对于一组数据,从第一个开始依此向后,两个两个的进行比较,让较大的数往下沉,较小的往上冒. 经过第1轮排序,可以将最大的元素排在最后.第二轮可以将第二大的元素排在倒数第二,这样当前不断的将当前最大的元素排在末尾,就像鱼吐泡泡一样依此上升,所以称为冒泡排序.
public static void bubbleSort(int [] nums){
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i+1; j < nums.length; j++) {
if(nums[j] < nums[i]){
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
}
}
快速排序
核心思想:先确定第一个元素的位置,保证它左边的元素都小于它,右边的元素都大于它,然后以该元素为分界点,用同样的方法为两边的数组排序。
例如:随意列出10个无序的数字,需要用到i,j两个变量,i在这列数的最左边,j在这列数的最右边,在这列数中随意找到一个数设置基准值(这里为了方便将第一个数设置为基准),首先让j向左移动,让i向右移动。
j找到一个比基准值小的数2停下来,然后i向右移动找到比基准值大的数6停下来,然后将i,j所指向的数进行交换。
交换后,j继续向左移动找到比基准值小的数4停下来,然后i向右移动找到比基准值大的数7停下来,然后将i,j所指向的数进行交换。
接下来j继续向左移动找到比基准值小的数3,i向右移动和j碰面,此时i和j在同一个位置上停下来,此时将i和j所指向的数和基准值进行交换,即将3和5进行交换。
def quitSort(left,right):
if left >= right:
return
i = left
j = right
key = arr[left]
while i < j:
while i < j and arr[j] >= key:
j -= 1
while i < j and arr[i] <= key:
i += 1
t=arr[j]
arr[j] = arr[i]
arr[i]=t
arr[left]=arr[i]
arr[i]=key
quitSort(left,i-1)
quitSort(i+1,right)
quitSort(0,len(arr)-1)
print(arr)
这里需要提一点的是,为什么每次都需要j先移动,因为当最后i和j相碰时,此时所指向的是j寻找到比基准值小的数字,然后和基准值交换能确保基准值左边的都是小于基准值的数字,但是如果i先右边移动的话,最后i和j相碰时,i和j所指向的是i寻找得比基准值大的数,此时和基准值相交换,基准值左边是有一个比基准值大的数,没有达到我们需要的排序效果。如果我们想要i先动,只需要把基准元素取成最后一个即可。
选择排序
简单选择排序
每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排序的数据元素排完 。
public static void selection(int [] nums){
for (int i = 0; i < nums.length - 1; i++) {
int j = i + 1;
int index = i;
for(; j < nums.length; j++){
if(nums[j] < nums[index]){
index = j;
}
}
if(index != i){
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
}
}