首页 > 代码库 > 插入排序(insert_sort)与 并归排序(merge_sort) 算法分析
插入排序(insert_sort)与 并归排序(merge_sort) 算法分析
(一)插入排序
算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
算法描述:
一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
(1)从第一个元素开始,该元素可以认为已经被排序
(2)取出下一个元素,在已经排序的元素序列中从后向前扫描
(3)如果该元素(已排序)大于新元素,将该元素移到下一位置
(4)重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
(5)将新元素插入到该位置后
(6)重复步骤2~5
如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。
源码实例:
#include <iostream> #include <algorithm> #include <cstdlib> using namespace std; class insert_sort_class { public: insert_sort_class(int *a, int n):p_array(a), n_array(n){}; ~insert_sort_class(); void insert_sort(); void print(); private: int *p_array; int n_array; }; insert_sort_class::~insert_sort_class() { } void insert_sort_class::insert_sort() { for(int i=1;i<n_array;++i) { int key = p_array[i]; int j=i-1; while((j>=0)&&(j<n_array-1)&&(p_array[j]>key)) { p_array[j+1]=p_array[j]; j -=1; } p_array[j+1] = key; } } void insert_sort_class::print() { for(int i=0;i<n_array;++i) cout<<p_array[i]<<" "; cout<<endl; } int main() { int array[10] = {7, 4, 9, 16, 18, 84, 23, 49, 52, 11}; insert_sort_class myInsertSort(array, 10); myInsertSort.print(); myInsertSort.insert_sort(); myInsertSort.print(); }
结果:
(二)归并排序
归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。时间复杂度为(nlg(n))
归并操作:
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
算法描述
归并操作的过程如下:
(1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
(2)设定两个指针,最初位置分别为两个已经排序序列的起始位置
(3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
(4)重复步骤3直到某一指针达到序列尾
(5)将另一序列剩下的所有元素直接复制到合并序列尾
说明:《算法导论》上采用哨兵的方法,来防止合并时越界。(数组大小扩展一位,放入足够大(或小)的哨兵)
源码实例:
#include <iostream> #include <algorithm> #include <cstdlib> using namespace std; class merge_sort_class { public: merge_sort_class(int *a, int n):p_array(a), n_array(n){}; ~merge_sort_class(); void merge_sort(int i, int j); void print(); protected: void merge(int *a, int p, int q, int r); private: int *p_array; int n_array; }; merge_sort_class::~merge_sort_class() { } void merge_sort_class::merge_sort(int i, int j) { if(i<j) { int q=(i+j-1)/2; merge_sort(i, q); merge_sort(q+1, j); merge(p_array, i, q, j); } } void merge_sort_class::merge(int *a, int p, int q, int r) { int m = q-p+1; int array1[m+1]; int n = r-q; int array2[n+1]; int b=0; int c=0; for(int i=0;i<m;++i) array1[i]=a[p+i]; array1[m]=1000; for(int i=0;i<n;++i) array2[i]=a[q+i+1]; array2[n]=1000; for(int j=p;j<=r;++j) { if(array1[b]<=array2[c]) { a[j]=array1[b]; b++; } else { a[j]=array2[c]; c++; } } } void merge_sort_class::print() { for(int i=0;i<n_array;++i) cout<<p_array[i]<<" "; cout<<endl; } int main() { int array[10] = {92, 4, 19, 16, 18, 84, 23, 49, 52, 11}; merge_sort_class myMergeSort(array, 10); myMergeSort.print(); myMergeSort.merge_sort(0, 9); myMergeSort.print(); }测试结果: