各个排序的时间复杂度
图源学益得
1. 冒泡排序
//输出时间:20793ms
public class Bubble {
public static void main(String[] args)
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
bubbleSort(array);
long l2 = System.currentTimeMillis();
long l3 = l2-l1;
System.out.println(l3);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i]+" ");
// }
}
public static void bubbleSort(double[] array)
{
double tmp = 0;
for(int i=0; i<array.length-1; i++)
{
for(int j=0; j<array.length-1-i; j++)
{
if(array[j] > array[j+1])
{
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}
}
2. 直接插入排序
//直接插入排序,第一个for循环遍历所有数组元素,第二个for循环判断这个元素比前面元素大或者小,大就break,小就互换位置
//注意引入tmp变量保存第一个for遍历的元素,可以用break的原因是前面的j个元素已经按升序排列好了
//输出时间:1874ms
public class DirectInsert {
public static void main(String[] args)
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
directInsertSort(array);
long l2 = System.currentTimeMillis();
System.out.println(l2-l1);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i]+" ");
// }
}
public static void directInsertSort(double[] array)
{
double tmp = 0;
// 注意这里是从i=1开始进行比较!
for(int i=1; i<array.length; i++)
{
tmp = array[i];
for(int j=i-1; j>=0; j--)
{
if(tmp < array[j])
{
array[j+1] = array[j];
array[j] = tmp;
}
else
{
break;
}
}
}
}
}
3. 希尔排序
//输出时间:22ms
public class Shell {
public static void main(String[] args)
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
shellSort(array);
long l2 = System.currentTimeMillis();
long l3 = l2 - l1;
System.out.println(l3);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i]+" ");
// }
}
public static void shellSort(double[] array)
{
double tmp = 0;
for(int h = array.length/2; h>0; h/=2)
{
for(int i=h; i<array.length; i++)
{
tmp = array[i];
for(int j=i-h; j>0; j-=h)
{
if(tmp < array[j])
{
array[j+h] = array[j];
array[j] = tmp;
}
else
{
break;
}
}
}
}
}
}
4. 简单选择排序
// 在第二个if循环中选举出一个最小的元素,记录它的值和下标,然后把它和第一个if循环的array[i]做交换
//输出时间:7570ms
public class SimpleChoosing {
public static void main(String[] args)
{
double[] array = new double[20];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
bubbleSort(array);
long l2 = System.currentTimeMillis();
long l3 = l2-l1;
System.out.println(l3);
for(int i=0; i<array.length; i++)
{
System.out.print(array[i]+" ");
}
}
public static void bubbleSort(double[] array)
{
double tmp = 0;
double tmp2 = 0;
int index = 0;
for(int i=0; i<array.length; i++)
{
tmp = array[i];
index = i;
for(int j=i+1; j<array.length; j++)
{
if(array[j] < tmp)
{
tmp = array[j];
index = j;
}
}
tmp2 = array[index];
array[index] = array[i];
array[i] = tmp2;
}
}
}
5. 快速排序
//输出时间:46ms
public class Fast {
public static void main(String[] args)
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
fastSort(array, 0, array.length-1);
long l2 = System.currentTimeMillis();
long l3 = l2-l1;
System.out.println(l3);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i]+" ");
// }
}
public static void fastSort(double[] array, int begin, int end)
{
// 注意这里的if,和视频里面用C写的不一样!
if(end > 0 && begin < end)
{
int x = begin;
int y = end;
double tmp = array[begin];
while(x < y)
{
while(tmp < array[y] && x < y)
{
y--;
}
if(x < y)
{
array[x] = array[y];
x++;
}
while(tmp > array[x] && x < y)
{
x++;
}
if(x < y)
{
array[y] = array[x];
y--;
}
}
array[x] = tmp;
fastSort(array, begin, x-1);
fastSort(array, x+1, end);
}
}
}
6. 堆排序
//先构建大顶堆(比较数组下标从长度一半的值-1到0的所有孩子节点),然后把最大的第一个元素放在最后一个位置。再构建除了后面的元素之外其它的元素的顶堆,
// 此时只用以第一个元素开头构建顶堆,然后把第一个元素放在此时的“最后一个”元素的位置,如此反复一下去
//输出时间:17ms
public class Heap {
public static void main(String[] args)
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
heapSort(array);
long l2 = System.currentTimeMillis();
long l3 = l2 - l1;
System.out.println(l3);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i]+" ");
// }
}
public static void heapSort(double[] array)
{
double tmp = 0;
int i;
for(i = (array.length/2)-1; i>=0; i--)
{
constructHeap(array, i, array.length-1);
}
for(i = array.length-1; i>0; i--)
{
tmp = array[0];
array[0] = array[i];
array[i] = tmp;
constructHeap(array, 0, i-1);
}
}
public static void constructHeap(double[] array, int root, int last)
{
int child = 0;
double tmp = array[root];
for(; 2*root+1 <= last; root = child)
{
child = 2*root + 1;
if(child + 1 <= last && array[child] < array[child + 1])
{
child++;
}
if(array[child] > array[root])
{
array[root] = array[child];
array[child] = tmp;
}
}
}
}
7. 归并排序
//输出时间:33ms
public class Merge {
public static void main(String[] args)
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = Math.random();
}
long l1 = System.currentTimeMillis();
mergeSort(array, 0, array.length-1);
long l2 = System.currentTimeMillis();
long l3 = l2 - l1;
System.out.println(l3);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i]+" ");
// }
}
public static void mergeSort(double[] array, int begin, int end)
{
if(begin >= end)
{
return;
}
int mid = (begin + end)/2;
mergeSort(array, begin, mid);
mergeSort(array, mid+1, end);
merge(array, begin, mid, end);
}
public static void merge(double[] array, int begin, int mid, int end)
{
int leftLength = mid - begin + 1;
int rightLength = end - mid;
int i = 0;
int j = 0;
// 注意这里k为什么等于begin而不是0,而i、j等于0
int k = begin;
double[] leftArray = new double[leftLength];
double[] rightArray = new double[rightLength];
for(i=0, k=begin; i<leftLength; i++, k++)
{
leftArray[i] = array[k];
}
for(j=0; j<rightLength; j++, k++)
{
rightArray[j] = array[k];
}
for(i=0, j=0, k=begin; i<leftLength && j<rightLength; k++)
{
if(leftArray[i] < rightArray[j])
{
array[k] = leftArray[i];
i++;
}
else
{
array[k] = rightArray[j];
j++;
}
}
if(j<rightLength)
{
for(; j<rightLength; j++)
{
array[k] = rightArray[j];
k++;
}
}
if(i<leftLength)
{
for(; i<leftLength; i++)
{
array[k] = leftArray[i];
k++;
}
}
}
}
8. 基数排序
//输出时间:40ms
public class Radix {
public static void main(String[] args) throws ArrayIndexOutOfBoundsException
{
double[] array = new double[100000];
for(int i=0; i<array.length; i++)
{
array[i] = 100*Math.random();
}
long l1 = System.currentTimeMillis();
radixSort(array);
long l2 = System.currentTimeMillis();
long l3 = l2-l1;
System.out.println(l3);
// for(int i=0; i<array.length; i++)
// {
// System.out.print(array[i] + " ");
// }
}
public static void radixSort(double[] array)
{
int i = 0;
double max = array[0];
int base = 1;
for(i=1; i<array.length; i++)
{
if(array[i] > max)
{
max = array[i];
}
}
double[] array2 = new double[array.length];
while(max / base > 0)
{
int[] bucket = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// 比较个位/十位/百位/千位...桶的0-9元素加1
for(i=0; i<array.length; i++)
{
bucket[(int)(array[i] / base) % 10 ]++;
}
// 为了确定各个元素放入array2的顺序,需要借助桶的个数并且作修改,来获取每个元素的下标
for(i=1; i<10; i++)
{
bucket[i] = bucket[i] + bucket[i-1];
}
// 先通过array的个位/十位/百位/千位对应的数字获取对应的桶元素,然后将这个桶元素-1获得array要放入array2的下标。由于每个桶元素不止
// 对应着一个array的元素,所以每次放入后要将桶元素减1
for(i=array.length-1; i>=0; i--)
{
array2[bucket[((int)array[i] / base) % 10] - 1] = array[i];
bucket[(int)(array[i] / base) % 10]--;
}
// 最后将array2的元素重新放回array中,完成一次个位/十位/百位...的基数排序
for(i=0; i<array.length; i++)
{
array[i] = array2[i];
}
// base自乘10,准备下一位的基数排序
base = base * 10;
}
}
}