几种常用的算法的时间空间复杂度
1、冒泡排序
思想:比较相邻的元素,如果第一个元素比第二个大,就交换位置,对每一对相邻的元素进行同样的操作。这样最后的元素应该是最大的数。排除最后一个数,针对前面的所有元素进行上述步骤,持续每次在越来越少的元素中找到最大。
算法 Java代码:
static void popSort(int[] a){
for(int i = 0; i < a.length-1; i++){
for(int j = i+1; j < a.length; j++){
if(a[i]>a[j]){
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
最后循环打印输出数组。
注意if中的代码,是经常用到的交换两个元素的位置的常用方法。
2、快速排序
思想:采用分治的策略,从数组选出一个数作为基准。分区过程,将比这个数大的数放在它的右边,比它小的数放在它的左边。再对左右空间重复上述,知道各区间只有一个元素。
快排是一种不稳定的排序。
算法 代码:
static void quickSort(int[] a, int l, int r){
if(l < r){
int i = l, j = r, x = a[l];
while(i < j){
while(i < j && a[j] > x) j--;
if(i < j) a[i++] = a[j];
while(i < j && a[i] < x) i++;
if(i < j) a[j--] = a[i];
}
a[i] = x;
quickSort(a,l,i-1);
quickSort(a,i+1,r);
}
}
3、选择排序
思想:从数据中选择一个最小的与第一个值交换,再从剩下的部分找出最小的与第二个交换,以此类推。。。
算法代码 :
static void selectSort(int [] a){
int minIndex = 0, temp = 0;
//minIndex保存最小下标。temp是用于连个元素进行交换的临时变量
for(int i = 0; i< a.length-1; i++){
minIndex = i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minIndex])
minIndex = j;
}
if(minIndex != i){
temp = a[minIndex];
a[minIndex] = a[i];
a[i] = temp;
}
}
}
4、直接插入排序
思想:
1. 插入排序, 从第二个数开始,先将第二个数做一个副本放在一旁(变量中)。
2 .第二个数同前一个数比较,小于则用前一个数覆盖第二个数, 然后将副本放在前一个数前面
3. 再将第三个数做一个副本取出,第三个数同前一个数比较,小于则用前一个数覆盖第三个数(此时第二个数位置空闲), 然后用副本同前一个数的前一个数比较,如果小于,则用前一个数的前一个数覆盖在原本的第二个位置上(此时第一个位置空闲), 将副本放入即可。
4. 将数组中接下来的数依次做与3类似步骤,以3类推将副本往前作比较。直到副本不小于比较的数则该轮插入结束
5. 重复4步骤,直到最后一个数
public static void insert_Sort(int[] a){
int temp;//设置一个临时变量,存放即将要插入的数。
for(int i = 1; i < a.length; i ++){
for(int j = i; j > 0; j --){
if(a[j]< a[j-1]){
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
//这几行代码是常用的将两个元素进行位置交换的方法
}
}
}
5、归并排序
思路:
将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?
可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。
设两个有序的子序列(相当于输入序列)放在同一序列中相邻的位置上:array[low..m],array[m + 1..high],先将它们合并到一个局部的暂存序列 temp (相当于输出序列)中,待合并完成后将 temp 复制回 array[low..high]中,从而完成排序。
//二路归并排序就是先将一个数组一半一半的分成若干个有序的数组,再进行组合
static void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
//将临时数组temp中的值复制到原来的数组中
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
//将数组进行多次划分,再进行合并排序
static void mergesort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
mergesort(a, first, mid, temp); //左边有序
mergesort(a, mid + 1, last, temp); //右边有序
mergearray(a, first, mid, last, temp); //再将二个有序数列合并
}
}
static Boolean MergeSort(int a[], int n)
{
int [] temp= new int[n];
if (temp == null)
return false;
mergesort(a, 0, n - 1, temp);
return true;
}