参考:https://blog.csdn.net/qq_33101675/article/details/78701270
常见排序算法介绍:https://blog.csdn.net/anneCoder/article/details/79751239
排序算法稳定性:
时间复杂度和空间复杂度的简单讲解:https://blog.csdn.net/halotrriger/article/details/78994122
常见算法总结:http://www.cnblogs.com/eniac12/p/5329396.html#s31
时间复杂度
首先要说的是,时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。
当我们面前有多个算法时,我们可以通过计算时间复杂度,判断出哪一个算法在具体执行时花费时间最多和最少。
常见的时间复杂度有:
常数阶O(1),
对数阶O(log2 n),
线性阶O(n),
线性对数阶O(n log2 n),
平方阶O(n^2),
立方阶O(n^3)
k次方阶O(n^K),
指数阶O(2^n)。
随着n的不断增大,时间复杂度不断增大,算法花费时间越多。
计算方法
①选取相对增长最高的项
②最高项系数是都化为1
③若是常数的话用O(1)表示
如f(n)=2*n^3+2n+100则O(n)=n^3。
空间复杂度
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
计算方法:
①忽略常数,用O(1)表示
②递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间
③对于单线程来说,递归有运行时堆栈,求的是递归最深的那一次压栈所耗费的空间的个数,因为递归最深的那一次所耗费的空间足以容纳它所有递归过程。
如:
<span style="color:#000000"><code><span style="color:#000088">int</span> a;
<span style="color:#000088">int</span> b;
<span style="color:#000088">int</span> c;
<span style="color:#000088">printf</span>(<span style="color:#009900">"<span style="color:#4f4f4f">%d</span> <span style="color:#4f4f4f">%d</span> <span style="color:#4f4f4f">%d</span> \n"</span>,a,b,c);</code></span>
它的空间复杂度O(n)=O(1);
<span style="color:#000000"><code><span style="color:#000088">int</span> fun(<span style="color:#000088">int</span> n,)
{
<span style="color:#000088">int</span> k=<span style="color:#006666">10</span>;
<span style="color:#000088">if</span>(n==k)
<span style="color:#000088">return</span> n;
<span style="color:#000088">else</span>
<span style="color:#000088">return</span> fun(++n);
}</code></span>
递归实现,调用fun函数,每次都创建1个变量k。调用n次,空间复杂度O(n*1)=O(n)。
算法稳定性
通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。
排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就 是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。
常见排序算法时间复杂度和空间复杂度
常见排序算法介绍
插入排序(Insertion sorting):将一个数据插入到有序数据中,构成长度加一的新有序数据,适用于少量数据的排序,时间复杂度O(n^2),是稳定的排序方法。
选择排序(Selection sorting):每次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,知道全部待排序的数据元素排完,是不稳定的排序方法。
堆排序(heap Sort):选择排序的改进。将无序数列构建成一个堆,根据升序、降序需求选择大顶堆或小顶堆;将堆顶元素与末尾元素交换,将最大元素“沉”到数组末端;重新调整结构;重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
冒泡排序(Bubble sorting):对相邻元素两两比较,顺序相反则进行交换,每走一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。
public static void bubbleSort(int[] a) {
for(int i=a.length-1; i>0; i--) { // n-1次扫描
for(int j=0; j<i; j++) {
if(a[j]>a[j+1]) {
swap(a, j, j+1);
}
}
}
}
private static void swap(int[] a, i, j) {
if(i = j) {
return;
}
int temp = a[i];
a[i] = a[j];
a[j] = a[i];
}
快速排序(Quick sort):对冒泡排序的改进。通过一趟排序将待排数据分割成比选定数据小和大的两部分,再依照此法对两部分数据进行快速排序。
归并排序(Merge Sort):采用了分治策略,将已有序的子序列合并,得到完全有序的序列。若将两个有序表合并成一个有序表,称为二路归并。
希尔排序(Shell Sort):也称缩小增量排序。把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件分成一组,算法便终止。