《算法》排序

通过学习《算法》,对几种排序算法做一个小结。首先展示不同算法的空间、时间等比较,后面对每一种具体描述。
排序算法对比

  1. 选择排序
    依此选择最小值从前往后排列,如图。
    选择排序
void mySort<Type>::selectSort(Type* root,int size)
{
	int N = size;
	int k;
	for (int i = 0; i < N; ++i)
	{
		k = i;
		for (int j = i + 1; j < N; ++j)
		{
			if (cmp(root[k], root[j]) > 0)
			{
				k = j;
			}
		}
		if (k != i)
		{
			Type tmp = root[k];
			root[k] = root[i];
			root[i] = tmp;
		}
	}
}
  1. 插入排序
    每次循环保证左边是排好顺序的。
    插入排序
void mySort<Type>::insertSort(Type* root, int size)
{
	int N = size;
	for (int i = 0; i < N; ++i)
	{
		for (int j = i + 1; j > 0; --j)
		{
			if (cmp(root[i], root[j]) > 0)
			{
				Type tmp = root[i];
				root[i] = root[j];
				root[j] = tmp;
			}
		}		
	}
}
  1. shell排序
    还是以插入排序的思想,对h格进行排序。
    shellsort
template <typename Type>
void sort<Type>::shell_sort(Type *root, int size)
{
	int i, j, grp;
	Type temp;
	for (grp = size / 2; grp > 0; grp /= 2) {
		for (i = grp; i < size; i++) {
			for (j = i - grp; j >= 0; j -= grp) {
				if (cmp(root[j], root[j + grp]) > 0) {
					temp = root[j];
					root[j] = root[j + grp];
					root[j + grp] = temp;
				}
			}
		}
	}		
}
  1. 归并排序
    在这里插入图片描述
    注意“归并”二字,体现了算法的思想和方法,用到递归和合并。该算法的思想是:合并两个已排好序列为一个序列。基于此思想结合“分治思想”,将一个随机序列分为Length/2份子序列,分别对子序列排序、合并,直到将整个序列排序。
    代码如下:
//--------原地归并抽象方法-------
template <typename Type>
void merge(Type *str, int lo, int mid, int hi) {
	int i = lo, j = mid + 1;
	Type* aux = new Type[hi+1];
	for (int k = lo; k <= hi; ++k)	//copy to aux[]
	{
		*(aux + k) = str[k];
	}
	for (int k = lo; k <= hi; ++k)	//sort subsequence
	{
		if (i > mid)	str[k] = aux[j++];
		else if (j > hi)	str[k] = aux[i++];
		else if (aux[i] > aux[j])	str[k] = aux[j++];
		else	str[k] = aux[i++];
	}
}
//up to button mergesort. 先分离再排序
template <typename Type>
void mergesort(Type *str, int lo, int hi)	//recursive to sort input sequence
{
	if (lo >= hi)	return;
	int mid = lo + (hi - lo) / 2;
	mergesort(str, lo, mid);	//sort the left of sequence
	mergesort(str, mid+1, hi);
	merge(str, lo, mid, hi);
}
//button to up mergesort. 先排序再合并
template <typename Type>
void mergesort(Type *str,int length)	//no recursive
{
	//int N = sizeof(str)/sizeof(str[0])-1;	
	/*记住一定要减1,因为此方法算得长度是包含'\0',所以要减1,才是有效长度。
	但是通过指针传入,sizeof(str)只是指针的大小,和操作系统有关,
	不能通过此方法获取数组长度。*/
	for(int sz = 1;sz < N;sz = sz + sz)
	{
		for(int lo = 0;lo < N-sz;lo += sz + sz)
		{
			merge(str, lo, lo + sz - 1, (lo+sz+sz-1>N-1)?N-1:lo+sz+sz-1);
		}
	}
}
  1. 快速排序
    也是一种“分治”的思想,过程是将一个sequence分为两段,分别排序后,整个sequence自然有序,和mergesort相互补充。
    在这里插入图片描述
    对比:
    mergesort: 递归调用发生在sequence处理之前
    quicksort: 递归调用发生在sequence处理之后
template <typename Type>
int partition(Type *str, int lo, int hi)
{
	int i = lo,j = hi+1;
	Type v = str[lo];
	while(true)
	{
		while(str[++i]<v)	if(i==hi)	break;	//思考为啥是++i和--j而不是i++和j--。
		while(str[--j]>v)	if(j==lo)	break;
		if(i>=j)	break;
		Type ex = str[i];
		str[i] = str[j];
		str[j] = ex;
	}
	Type ex = str[lo];
	str[lo] = str[j];
	str[j] = ex;
	return j;
}

template <typename Type>
void quicksort(Type *str, int lo, int hi)
{
	if(hi<=lo)	return;
	int j = partition(str, lo, hi);
	quicksort(str, lo, j-1);
	quicksort(str, j+1, hi);
}

快速排序的改进
和大多数递归排序一样,基于以下两点:

  1. 对于小数组,快速排序比插入排序慢
  2. 因为递归,快速排序的quicksort()会调用自己
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值