《算法》排序

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

  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()会调用自己
Python提供了许多内置的排序算法排序函数,以下是其中一些常见的算法排序方式: 1. 内置函数 `sorted()`:这是Python的内置函数,可以对列表、元组或其他可迭代对象进行排序。它使用的是Timsort算法,结合了插入排序和归并排序的优势,具有稳定性和高效性。 2. `list.sort()` 方法:这个方法用于对列表进行原地排序。它与 `sorted()` 函数类似,使用的也是Timsort算法,但不会创建新的排序副本,而是直接在原始列表上进行排序。 3. 冒泡排序(Bubble Sort):这是一种简单的排序算法,它反复地交换相邻的元素,将最大(或最小)的元素逐步“冒泡”到列表的末尾。 4. 插入排序(Insertion Sort):这种排序算法将未排序的元素逐个插入到已排序序列中的正确位置。它在小规模或基本有序的列表上表现良好。 5. 选择排序(Selection Sort):该算法每次从未排序的部分中选择最小(或最大)的元素,并将其放置在已排序部分的末尾。 6. 快速排序(Quick Sort):这是一种常用且高效的分治算法。它选择一个基准元素,将列表分为左右两个子列表,左边的元素小于基准元素,右边的元素大于基准元素,然后递归地对子列表进行排序。 7. 归并排序(Merge Sort):这是一种基于分治的排序算法,它将列表递归地划分为较小的子列表,然后逐步合并子列表以获得最终的排序结果。 这只是一些常见的排序算法,Python中还有其他一些排序算法,如堆排序、计数排序、桶排序等。选择合适的排序算法取决于数据的规模和特点,以及对性能和稳定性的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值