算法基础第一篇:排序汇总(1)

来源:互联网 发布:找出两列数据的重复项 编辑:程序博客网 时间:2024/05/29 14:28

废话不多说,从排序开始。

1.冒泡排序:

       冒泡排序是最最最简单的排序算法,大多数教材都以此为入门材料。它的思想就是从第一个数开始,和后面的每一个数作比较,选出最小(大)的放在第一个位置。然后再从剩余的数中选出最小的,放在第二个位置。。。依次遍历直到所有数排好顺序。

这里以一个整形数组为例,写个示范代码(src为源数组):

<pre class="cpp" name="code">for(int i=0; i<src.length; i++) {for(int j=i; j<src.length; j++) {if(src[i] > src[j]) {int temp = src[i];src[i] = src[j];src[j] = temp;}}}

冒泡算法的结构很简单,但是它做了烦琐的比较,导致在数据量很大时(比如1亿个数排序),由于比较次数较多,性能会下降。尤其值得指出的是,即使源数组顺序已经排好,使用冒泡法的时候也会做C*n^2次比较,即其最好、最坏时间复杂度都是O(n^2)。

2.插入排序 

        插入排序的基本思想是,从数组的第二个数开始,将其同前面的数比较,插入顺序的位置,就跟我们抓扑克牌一样,总是把抓到的牌插入手中已有的牌的合适的位置。

简单的排序代码如下:

int key;for(int j=1; j<src.length; j++) {key = src[j];int i = j-1;while(i>=0 && src[i] > key) {src[i+1] = src[i];i = i-1;}src[i+1] = key;}

        插入排序的时间复杂度也是O(n^2),但是在最好情况下,复杂度为O(n),因此其性能总的来说某些情况下可能会优于冒泡排序。


3.归并排序

       归并排序利用分治策略进行排序,基本思想是,从源数组中间递归地将其分为两个子数组,然后两个子数组合并,合并规则是按顺序将两个数组的元素合并。举个例子,一个子数组是{2,5,7,9},另一个是{3,4,6,8},合并后的数组应该是{2,3,4,5,6,7,8}。

       归并排序的简单实现代码如下:

       (1) 先定义一个合并子数组的函数:

void merge(int a[],int p,int q,int r){int n1 = q - p + 1;int n2 = r - q;int *L_array = new int[n1+1];int *R_array = new int[n2+1];for(int i=0; i<n1; i++){*(L_array+i) = a[p+i];}*(L_array+n1) = 10000;for(int i=0; i<n2; i++) {*(R_array+i) = a[q+i+1];}//哨兵元素,防止越界*(R_array+n2) = 10000;int i = 0;int j = 0;for(int k=p; k<=r; k++) {if(L_array[i] <= R_array[j]){a[k] = L_array[i];i++;} else {a[k] = R_array[j];j++;}}delete []R_array;delete []L_array;}

          (2). 再定义一个递归函数进行归并排序:

void mergeSort(int a[],int p,int r){int q;if(p < r){q = (r+p)/2;mergeSort(a,p,q);mergeSort(a,q+1,r);merge(a,p,q,r);}}
归并排序的时间复杂度为O(nlogn),它相对于插入排序,在数据量较大时性能得到了较大提升。但是,归并排序需要相对较多的额外存储空间来保存子数组。即以空间换取速度的提升。 
 


0 0
原创粉丝点击