排序问题合集

从大一学c开始接触了不少常用的排序算法,今天有空简单整理一下,希望对大家的学习有所帮助:

1.快速排序:

快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列



#include<iostream>
using namespace std;
void qsort(int a[], int b, int e) {
	if (e> b) {
		int i= b, j= e, k= a[b];
		while (i< j) {
			while (i< j&&a[j]>= k) j--;
			a[i]= a[j];
			while (i< j&&a[i]<= k) i++;
			a[j]= a[i];
		}
		a[i]= k;
		qsort(a, b, i- 1);
		qsort(a, i+ 1, e);
	}
}
main() {
	int a[6];
	for (int i= 0; i< 6; i++) cin>> a[i];
	qsort(a, 0, 5);
	for (int i= 0; i< 6; i++) cout<< a[i]<< "-";
}

另一种分治形式:

#include<iostream>
using namespace std;
void swap(int *a, int* b) {
	if (a!= b) {
	    *a= *a^ *b;
	    *b= *a^ *b;
	    *a= *a^ *b;
	}
}
int partion(int a[], int s, int e) {
	int j= s- 1;
	for (int i= s; i< e; i++) {
		if (a[i]< a[e]) {
			j++;
			swap(&a[i], &a[j]);
		}
	}
	swap(&a[j+ 1], &a[e]);
	return j+ 1;
}
void qsort(int a[], int s, int e) {
	if (s< e) {
		int m= partion(a, s, e);
		qsort(a, s, m- 1);
		qsort(a, m+ 1, e); 
	}
}
main() {
	int a[5]= {3, 0, 5, 1, 55};
	qsort(a, 0, 4);
	for (int i= 0; i< 5; i++) cout<< a[i]<< "-";
}

尾递归优化:

快排算法和大多数分治排序算法一样,都有两次递归调用。但是快排与归并排序不同,归并的递归则在函数一开始, 快排的递归在函数尾部,这就使得快排代码可以实施尾递归优化。第一次递归以后,变量p就没有用处了, 也就是说第二次递归可以用迭代控制结构代替。虽然这种优化一般是有编译器实施,但是也可以人为的模拟:

采用这种方法可以缩减堆栈深度,由原来的O(n)缩减为O(logn)。




2.归幷排序:

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路 归并
归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

#include<iostream>
using namespace std;
 void merge(int a[], int t[], int s, int m, int e) {
 	int i= s, k= s, j= m+ 1;
 	while (i!= m+ 1&&j!= e+ 1) {
 		if (a[i]>= a[j]) {
 			t[k++]= a[j++];
		 } else {
		 	t[k++]= a[i++];
		 }
	 }
	 while (i!= m+ 1) t[k++]= a[i++];
	 while (j!= e+ 1) t[k++]= a[j++];
	 for (int i= s; i< e+ 1; i++) a[i]= t[i];
 }
 void mergesort(int a[], int t[], int s, int e) {
 	if (s< e) {
 		int m= (s+ e)/ 2;
 		mergesort(a, t, s, m);
 		mergesort(a, t, m+ 1, e);
 		merge(a, t, s, m, e);
	 }
 }
main() {
 	int t[6], a[6]= {7, 3, 4, 1, 8, 0};
 	mergesort(a, t, 0, 5);
 	for (int i= 0; i< 6; i++) cout<< a[i]<< "-";
 }





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值