#include <iostream>
using namespace std;
#define MAXSIZE 20
typedef struct
{
	int r[MAXSIZE+1];
	int length;
}SqList;
//输入记录
void Input(SqList &L)
{
	cin>>L.length;
	for(int i=1;i<=L.length;i++)
		cin>>L.r[i];
}
//输出记录
void OutLook(SqList &L)
{
	for(int i=1;i<=L.length;i++)
		cout<<L.r[i]<<" ";
}
//----------------------------------------
//冒泡排序
//----------------------------------------
void BubbleSort(SqList &L)
{
	int tag,bound;
	int j;
	tag=0;//先置标志位为0
	bound=0;//存储已经排好序的边界
	while(tag==0)
	{
		tag=1;/*将标志位改成1,若经过下面的一趟排序,tag的值都没有被改成0,说明if语句里的内容就没有被执行,
		也就是说,这组记录已经是有序的了,则就可以结束while循环了。这就是标志位的妙用啊!*/
		for(j=L.length-1;j>bound;j--)
			if(L.r[j+1]<L.r[j])
			{
				L.r[0]=L.r[j+1];
				L.r[j+1]=L.r[j];
				L.r[j]=L.r[0];
				tag=0;
			}
		bound=j+1;
	}
}
//-------------------------------------
//快速排序
//-------------------------------------
int GetPivot(SqList &L,int low,int high)
{
	int pivot;
	L.r[0]=L.r[low];//先将枢轴位置的值暂存在首单元中
	pivot=L.r[low];
	while(low<high)
	{
		while(low<high && L.r[high]>=pivot)
			high--;//该循环就是从后往前,找到第一个小于pivot的值的位置
		L.r[low]=L.r[high];//这里虽然没有真正的实现交换,但这种写法类似于交换,且效率比真正的交换要好
		while(low<high && L.r[low]<=pivot)
			low++;//从前往后找第一个大于pivot的值的位置
		L.r[high]=L.r[low];
	}
	L.r[low]=L.r[0];//此时的low就是枢轴位置,将暂存在首单元的值再赋值给它。
	return low;
}
void QSort(SqList &L,int low,int high)
{
	int pivot;
	if(low<high)
	{
		pivot=GetPivot(L,low,high);
		QSort(L,low,pivot-1);//对左区间进行递归排序
		QSort(L,pivot+1,high);//对右区间进行递归排序
	}
}
void QuickSort(SqList &L)
{
	QSort(L,1,L.length);
}
void main()
{
	//freopen("in.txt","r",stdin);
	SqList L;
	Input(L);
	//BubbleSort(L);
	QuickSort(L);
	OutLook(L);
}

其实很早就听说过冒泡排序,当时是从别人嘴里听来的,感觉那人说这“冒泡排序”时,很神气的样子和口气,唉,说来很惭愧,现在才搞懂这个冒泡,其实也蛮简单的。还有这个快速排序,今天数据结构实验课的考试,就考的这个,我正好没有把进度拉到这来,结果,考试时,费了我很大劲,才把这个写出来可是由于快要下课了,老师没来得及看……悲剧啊……

言归正传,还是说一下这两个算法的特性吧:

1、冒泡排序,时间复杂度为O(n2),空间复杂度为O(1),它是一种稳定的排序方法,适用于待排序记录基本有序,或是数目较少的场合。其实它的特性和直接插入排序很像的。

2、快速排序,平均时间复杂度为O(nlog2n),空间复杂度为O(n)(因为需要一个栈来实现递归),它是一种不稳定的排序,适用于待排序记录个数很大且原始记录随机排列的情况。