用C++交换排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C++交换排序相关的知识,希望对你有一定的参考价值。

所谓交换,就是根据序列中两个记录值的比较结果来对换这两个记录在序列中的位置。交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。常见的交换排序有冒泡排序(Bubble Sort),鸡尾酒排序(Cocktail Sort),奇偶排序(OddEven Sort),地精排序(Gnome Sort),快速排序(Quick Sort),臭皮匠排序(Stooge Sort),梳排序(Comb Sort),Bogo排序(Bogo sort)。下面介绍前六种:
(一)冒泡排序
最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n^2)
最差空间复杂度:总共O(n),需要辅助空间O(1)
稳定性:稳定
冒泡排序(Bubble Sort),它重复地走访过要排序的数列,一次比较两个元素如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序算法的运作如下:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

实现代码:

[cpp] view plaincopy
void BubbleSort(int *a, int len)

for (int i=0; i<len; i++)

for (int j=len-1; j>i; j--)

if (a[j]<a[j-1])
swap(a[j], a[j-1]);




(二)鸡尾酒排序

最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n^2)
稳定性:稳定
鸡尾酒排序(Cocktail sort),是冒泡排序的一种变形。它与冒泡排序的不同之处在于排序时是以双向在序列中进行排序。数组中的数字本是无规律的排放,先对数组从左到右进行冒泡排序(升序),把最大值放到最右端,然后对数组从右到左进行冒泡排序(降序),把最小的数字放到最左端。然后再以此类推,以此改变冒泡的方向,并不断缩小未排序元素的范围。直到在一趟双向冒泡后没有发生交换,排序结束。

实现代码:

[cpp] view plaincopy
void CocktailSort(int* a, int len)

int bottom = 0;
int top = len-1;
bool swapped = true;

while (swapped)

swapped = false;
for (int i=bottom; i<top; i++)

if (a[i]>a[i+1])

swap(a[i], a[i+1]);
swapped = true;


top = top-1;

for (int i=top; i>bottom; i--)

if (a[i]<a[i-1])

swap(a[i], a[i-1]);
swapped = true;


bottom = bottom+1;



(三)奇偶排序

最差时间复杂度:O(n^2)
稳定性:稳定
奇偶排序(OddEven Sort),是一种相对简单的排序算法,最初发明用于有本地互联的并行计算。此算法通过比较数组中相邻的(奇-偶)位置数字对,如果该奇偶对是错误的顺序(第一个大于第二个),则交换。下一步重复该操作,但针对所有的(偶-奇)位置数字对。如此交替下去,直到不发生交换,则排序结束。
在并行计算排序中,使用该算法,每个处理器对应处理一个值,并仅有与左右邻居的本地互连。所有处理器可同时与邻居进行比较、交换操作,交替以奇-偶、偶-奇的顺序。该算法由Habermann在1972年最初发表并展现了在并行处理上的效率。但在单处理器串行运行此算法,类似冒泡排序,较为简单但效率并不特别高。

实现代码:

[cpp] view plaincopy
void OddEvenSort(int *a, int len)

bool swapped = true;
while (swapped)

swapped = false;
for (int i=0; i<len-1; i=i+2)

if (a[i]>a[i+1])

swap(a[i], a[i+1]);
swapped = true;


for (int i=1; i<len-1; i=i+2)

if (a[i]>a[i+1])

swap(a[i], a[i+1]);
swapped = true;





(四)地精排序

最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n^2)
稳定性:稳定
地精排序(Gnome Sort),被Dick Grune称为最简单的排序算法。整个算法只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好,然后继续前进,前进到数组最后一个数结束。此排序算法虽然代码极短,但效率不高。

实现代码:

[cpp] view plaincopy
void GnomeSort(int *a, int len)

int i=0;
while (i<len)

if (i==0 || a[i-1]<=a[i])
i++;

else
swap(a[i], a[i-1]);
i--;




(五)快速排序

最差时间复杂度:O(n^2)
最优时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)
稳定性:不稳定
快速排序(Quick Sort),使用分治法策略来把一个串行分为两个子串行,左边子串的值总小于右边的子串。此算法的三个步骤:
1.分解:将数组A[l...r]划分成两个(可能空)子数组A[l...p-1]和A[p+1...r],使得A[l...p-1]中的每个元素都小于等于A(p),而且,小于等于A[p+1...r]中的元素。下标p也在这个划分过程中计算。
2.解决:通过递归调用快速排序,对数组A[l...p-1]和A[p+1...r]排序。
3.合并:因为两个子数组时就地排序,将它们的合并并不需要操作,整个数组A[l..r]已经排序。

实现代码(其他实现方法见“三种快速排序算法的实现”):

[cpp] view plaincopy
int partition(int* a, int left, int right)

int x = a[right];
int i = left-1, j = right;
for (;;)

while(a[++i] < x)
while(a[--j] > x) if(j==left) break;
if(i < j)
swap(a[i], a[j]);
else break;

swap(a[i],a[right]);
return i;


void quickSort(int* a, int left, int right)

if (left<right)

int p = partition(a, left, right);

quickSort(a, left, p-1);
quickSort(a, p+1, right);



(六)臭皮匠排序

最差时间复杂度:O(n^2.7)
臭皮匠排序(Stooge Sort),是一种低效的排序算法,在《算法导论》第二版第7章的思考题中被提到,是由Howard Fine等教授提出的所谓“漂亮的”排序算法。将数列平分为三个子串,依次递归排序前两个子串、后两个子串、前两个子串,最后确保整个数列有序。此算法在最坏情况下的递归式为T(n) = 3T(2n/3) + 1。由主定理很容易知道它的算法复杂性为:T(n) = O(n^log(3/2, 3))。很显然log(3/2, 3))>2,也就是说这个算法比插入排序的O(n^2)性能还差。

实现代码:

[cpp] view plaincopy
void StoogeSort(int *a, int i, int j)

if(a[i]>a[j])
swap(a[i], a[j]);
if((i+1)>=j)
return;
int k = (j-i+1)/3;
StoogeSort(a, i, j-k);
StoogeSort(a, i+k, j);
StoogeSort(a, i, j-k);
参考技术A #include<iostream.h>
void main()

int a,b,temp;
cout<<"请输入第一个数:";
cin>>a;
cout<<"请输入第二个数:";
cin>>b;
temp=a;a=b;b=temp;
cout<<"交换次序后第一个数为:"<<a<<"第二个数为:"<<b<<endl;

测试通过~~~
参考技术B 能否将要求说得清楚些? 参考技术C void swap(int &a,int &b)

int temp;
temp=a;
a=b;
b=temp;
本回答被提问者采纳

C++实现各种交换排序(冒泡,快速)

冒泡排序:

代码如下:

#include <iostream>
using namespace std;

void BubbleSort(int *a, int len)
{//数组下标从0开始
	for (int i = 1;i<=len-1;i++)//共需要len-1趟
		for (int j = 1; j <= len - i; j++)//第i趟的比较次数是len-i次
			if (a[j - 1] > a[j])
			{
				int temp = a[j - 1];
				a[j - 1] = a[j];
				a[j] = temp;
			}
}

int main()
{
	int a[] = { 1231,34,532,5,4,124,214,12,3,14 };
	BubbleSort(a, 10);
	for (int i = 0; i < 10; i++) cout << a[i] << " ";
	cout << endl;
	return 0;
}

冒泡排序(优化):

代码如下:

#include <iostream>
using namespace std;

void BubbleSort(int *a, int len)
{//数组下标从0开始
	bool flag = true;
	for (int i = 1; i <= len - 1 && flag; i++)//共需要len-1趟
	{					
		flag = false;
		for (int j = 1; j <= len - i; j++)//第i趟的比较次数是len-i次
			if (a[j - 1] > a[j])
			{
				flag = true;
				int temp = a[j - 1];
				a[j - 1] = a[j];
				a[j] = temp;
			}
	}
}

int main()
{
	int a[] = { 1,3,54,554,4264,5234,68658,70000,88888,999999 };
	BubbleSort(a, 10);
	for (int i = 0; i < 10; i++) cout << a[i] << " ";
	cout << endl;
	return 0;
}

快速排序:

代码如下:

#include <iostream>
using namespace std;
int Partition(int *a, int low, int high);
void QSort(int *a, int low, int high)
{//数组下标从1开始
	if (low < high)
	{
		int pivotloc = Partition(a, low, high);

		QSort(a, low, pivotloc - 1);
		QSort(a, pivotloc + 1, high);
	}
}

int Partition(int *a, int low, int high)
{
	a[0] = a[low];
	int pivotkey = a[low];
	while (low < high)
	{
		while (low < high && a[high] >= pivotkey) --high;
		a[low] = a[high];
		while (low < high && a[low] <= pivotkey) ++low;
		a[high] = a[low];
	}
	a[low] = a[0];
	return low;
}


int main()
{
	int a[] = { 0,123,14124,4,214,23,4,324,24,124,24 };
	QSort(a, 1, 10);
	for (int i = 1; i <= 10; i++) cout << a[i] << " ";
	cout << endl;
	return 0;
}

以上是关于用C++交换排序的主要内容,如果未能解决你的问题,请参考以下文章

C++实现各种交换排序(冒泡,快速)

C++实现冒泡排序和选择排序算法

冒泡排序

有啥算法是相邻交换排序的(除了冒泡以外)

最少交换次数

C++算法之——常用算法总结