首页 > 代码库 > 插入排序(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();
}
测试结果: