#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)(因为需要一个栈来实现递归),它是一种不稳定的排序,适用于待排序记录个数很大且原始记录随机排列的情况。