1、冒泡排序
(1)基本思想:
(2)排序过程:
(3)算法分析:
#include <iostream>
#include <vector>
using namespace std;
void BubbleSort(int r[],int n)
{//对r[1]~r[n]排序
int exchange=n;
while(exchange)
{
int bound=exchange;//上次交换的位置
exchange=0;
for(int j=1;j<bound;j++)//只需比较到上次最后发生交换的位置
{
if(r[j]>r[j+1])
{
int temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
exchange=j;//最终记录最后一次交换的位置
//j是无序区最后一个数的位置
}
}
for(int j=1;j<=n;j++) cout<<r[j]<<' ';
cout<<endl;
}
}
int main()
{
int input[]={0,49,38,65,97,76,13,27,49};
int length=sizeof(input)/sizeof(int);
cout<<"原数组:"<<endl;
for(int i=1;i<=length-1;i++)
{
cout<<input[i]<<' ';
}
cout<<endl<<"排序过程:"<<endl;
BubbleSort(input,length-1);
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
void BubbleSort1(int r[],int n)
{//对r[1]~r[n]排序
int exchange=1;
for(int i=1;i<n&&exchange;i++)//只需比较到上次最后发生交换的位置
{
exchange=0;
for(int j=1;j<n-i+1;j++)
//首先对前n个数比较,然后对前n-1个比...对前2个比,完成。
{
if(r[j]>r[j+1])
{
int temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
exchange=1;//发生了交换
}
}
for(int j=1;j<=n;j++) cout<<r[j]<<' ';
cout<<endl;
}
}
int main()
{
int input[]={0,49,38,65,97,76,13,27,49};
int length=sizeof(input)/sizeof(int);
cout<<"原数组:"<<endl;
for(int i=1;i<=length-1;i++)
{
cout<<input[i]<<' ';
}
cout<<endl<<"排序过程:"<<endl;
BubbleSort1(input,length-1);
return 0;
}
该算法只记录了每趟排序是否发生了交换,但没有记录上界。故,第一趟是对前n个数比较,第二趟是对前n-1个数比较,......,最后对前2个数比较。结束。#include <iostream>
#include <vector>
using namespace std;
void BubbleSort2(int r[],int n)
{//对r[1]~r[n]排序
for(int i=1;i<n;i++)//只需比较到上次最后发生交换的位置
{
for(int j=1;j<n-i+1;j++)
//首先对前n个数比较,然后对前n-1个比...对前2个比,完成。
{
if(r[j]>r[j+1])
{
int temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
}
}
for(int j=1;j<=n;j++) cout<<r[j]<<' ';
cout<<endl;
}
}
int main()
{
int input[]={0,49,38,65,97,76,13,27,49};
int length=sizeof(input)/sizeof(int);
cout<<"原数组:"<<endl;
for(int i=1;i<=length-1;i++)
{
cout<<input[i]<<' ';
}
cout<<endl<<"排序过程:"<<endl;
BubbleSort2(input,length-1);
return 0;
}
该算法既没记录每趟是否发生元素交换,也没记录上界,效率最低,但最简单,故人们常用。2、快速排序
(1)基本思想:
快速排序采用的思想是分治思想。
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。对左右分区递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
(2)步骤:
(3)算法分析:
快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。
最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)
在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlgn)
尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。
快速排序不稳定。#include <iostream>
#include <vector>
using namespace std;
int Partition(int r[],int s,int t)
{
int x=r[s];//选r[s]为基准
int i=s,j=t;
while(i<j)
{
while(i<j&&r[j]>=x) j--;
if(i<j) r[i]=r[j];
while(i<j&&r[i]<=x) i++;
if(i<j) r[j]=r[i];
}
r[i]=x;//基准放到正确位置
for(int i=s;i<=t;i++) cout<<r[i]<<' ';
cout<<endl;
return i;//基准位置
}
void QuickSort(int r[],int first,int end)
{
if(first<end)
{
int pivot=Partition(r,first,end);
QuickSort(r,first,pivot-1);
QuickSort(r,pivot+1,end);
}
}
int main()
{
int input[]={49,38,65,97,76,13,27,49};
int length=sizeof(input)/sizeof(int);
cout<<"原数组:"<<endl;
for(int i=0;i<length;i++)
{
cout<<input[i]<<' ';
}
cout<<endl<<"排序过程:"<<endl;
QuickSort(input,0,length-1);
return 0;
}
(4)快速排序非递归形式
void QuickSort2(int r[],int low,int high)
{//在序列low~high中进行非递归快速排序
int size=sizeof(r)/sizeof(int);
int s[size+1][2];//二维数组s作为桟,size+1为大于n的常量
int top=-1;//桟顶指针
do
{
while(low<high)
{
int i=Partition(r,low,high);//基准位置
top=top+1;
s[top][0]=i+1;//s第1列记录划分的右区间的下界
s[top][1]=high;//s第2列记录划分的右区间的上界
high=i-1;
}
if(top>=0)
{
low=s[top][0];//出桟
high=s[top][1];
top--;
}
}while((top!=-1)||low<high);
}
#include <iostream>
#include <vector>
using namespace std;
int Partition(int r[],int s,int t)
{
int x=r[s];//选r[s]为基准
int i=s,j=t;
while(i<j)
{
while(i<j&&r[j]>=x) j--;
if(i<j) r[i]=r[j];
while(i<j&&r[i]<=x) i++;
if(i<j) r[j]=r[i];
}
r[i]=x;//基准放到正确位置
for(int i=s;i<=t;i++) cout<<r[i]<<' ';
cout<<endl;
return i;//基准位置
}
void QuickSort2(int r[],int low,int high)
{//在序列low~high中进行非递归快速排序
int size=sizeof(r)/sizeof(int);
int s[size+1][2];//二维数组s作为桟,size+1为大于n的常量
int top=-1;//桟顶指针
do
{
while(low<high)
{
cout<<"排序:";
int i=Partition(r,low,high);//基准位置
top=top+1;
cout<<"top="<<top<<' ';
s[top][0]=i+1;//s第1列记录划分的右区间的下界
cout<<"s[top][0]:"<<s[top][0]<<' ';
s[top][1]=high;//s第2列记录划分的右区间的上界
cout<<"s[top][1]:"<<s[top][1]<<' '<<"进桟"<<endl;
high=i-1;
}
if(top>=0)
{
low=s[top][0];//出桟
cout<<"low:"<<low<<' ';
high=s[top][1];
cout<<"high:"<<high<<' '<<"出桟"<<endl;
top--;
cout<<"top:"<<top<<' '<<endl;
}
}while((top!=-1)||low<high);
}
int main()
{
int input[]={49,38,65,97,76,13,27,49};
int length=sizeof(input)/sizeof(int);
cout<<"原数组:"<<endl;
for(int i=0;i<length;i++)
{
cout<<input[i]<<' ';
}
cout<<endl<<"排序过程:"<<endl;
QuickSort2(input,0,length-1);
return 0;
}