您的位置:首页 > 编程语言

几种常见的排序算法 及代码实现

2016-09-27 22:17 405 查看


假设需要排序的数一共有n个

简单选择排序

每次从n个数中选择最小的一个放在还未排序的数的最前面,共n-1次。

- 算法复杂度O(n²)

直接插入排序

每次将待排序的数插入在已排序的数中,共n-1次。

- 算法复杂度:O(n) - O(n²)

冒泡排序

每次比较相邻两个元素的值,如果前者大于后者,则交换。一趟之后,最大的元素沉底。共n-1趟。如果每趟没有发生交换,则说明已经排好。

- 算法复杂度:O(n) - O(n²)

快速排序

假设选择第一个数字为基准数,指针i从前向后移动,指针j从后向前移动。i在移动时指向一个大于基准数的值,j指向一个小于基准数的值,此时,若i<=j时,交换两个指针的值,之后继续移动指针、判断、交换。当i>j时,将j指向的值和基准数交换。

- 算法复杂度:O(nlogn) - O(n²)

#include<iostream>
#include<fstream>
#include<ctime>
#include<stdlib.h>
using namespace std;
#define SIZE  50 //200,000个数据
/*
int time()
{
time_t t0;
time(&t0);
cout<<t0;
return t1-t0;
}*/

void Swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}

template <class T>
void SelectSort(int A[], int n)
{
int small;
for (int	i=0; i<n-1; i++)
{      							//执行n-1趟
small=i;                        //先假定待排序序列中第一个元素为最小
for (int j=i+1;j<n;j++)         //每趟扫描待排序序列n-i-1次
if (A[j]<A[small]) small=j; //如果扫描到一个比最小值元素还小的,则记下其下标
Swap(A[i],A[small]);            //最小元素与待排序序列中第一个元素交换
}
}

template <class T>
void InsertSort(T A[], int n)
{
for(int i=1; i<n; i++){                //执行n-1趟
int j=i;
T temp=A[i];                      //待插入元素存入临时变量
while(j>0&&temp<A[j-1])
{       //从后往前查找插入位置
A[j]=A[j-1];
j--;             //A[j-1]元素后移,j指针前移
}
A[j]=temp;                         //待插入元素存入找到的插入位置
}
}

template <class T>
void BubbleSort(T A[], int n)
{
int i,j,last;
i=n-1;
while (i>0){                    //最多进行n-1趟
last=0;                     //进入循环就将last置成0
for (j=0; j<i; j++)          //从上往下进行相邻元素的两两比较
if (A[j+1]<A[j]){
Swap(A[j],A[j+1]);  //由于后者小,故交换
last=j;              //有交换就将last置成j
}
i=last;                        //如果一趟排序中没有交换元素,则last为0
}
}

template <class T>
void QuickSort(T A[], int n)
{
QSort(A,0,n-1);                   //以初始序列为待排序序列开始快速排序
}
template <class T>
void QSort(T A[], int left, int right)    //left和right为待排序序列的下界和上界
{
int i,j;
if (left<right){                     //若待排序序列多于一个元素,则继续快速排序
i=left; j=right+1;               //确定待排序序列的游动指针i,j
do{                              //开始一趟快速排序,A[left]作为分割元素
do i++;while (A[i]<A[left]);  //i指针从左往右找第一个分割元素的元素
do j--; while (A[j]>A[left]);//j指针从右往左找第一个分割元素的元素
if (i<j) Swap(A[i],A[j]);    //若i<j,则交换两个元素
}while (i<j);                    //若i<j,则继续本趟排序
Swap(A[left],A[j]);             //交换分割元素A[left]和A[j]的位置
QSort(A,left,j-1);               //对低端序列快速排序
QSort(A,j+1,right);             //对高端序列快速排序
}
}

template <class T>
void Merge(T A[],int i1,int j1,int i2,int j2)
{  // i1,j1是子序列1的下、上界,i1,j2是子序列2的下、上界
T *Temp=new T[j2-i1+1];             //分配能存放两个子序列的临时数组
int i=i1,j=i2,k=0;                   //i,j是两个子序列的游动指针,k是Temp的游动指针
while (i<=j1&&j<=j2)                //若两个子序列都不空,则循环
if (A[i]<=A[j]) Temp[k++]=A[i++];   //将A[i]和A[j]中较小的存入Temp[k]
else Temp[k++]=A[j++];
while (i<=j1) Temp[k++]=A[i++];     //若第一个子序列中还有剩余的就存入Temp
while (j<=j2) Temp[k++]=A[j++];     //若第二个子序列中还有剩余的就存入Temp
for (i=0; i<k; i++) A[i1++]=Temp[i]; //将临时数组中的元素倒回A
delete [] Temp;
}

template <class T>
void MergeSort(T A[], int n)
{
int i1,j1,i2,j2;      //i1,j1是子序列1的下、上界,i2,j2是子序列2的下、上界
int size=1;                      //子序列中元素个数,初始化为1。
while (size<n){
i1=0;
while (i1+size<n){ //若i1+size<n,则说明存在两个子序列,需再两两合并
i2=i1+size;                  //确定子序列2的下界
j1=i2-1;               //确定子序列1的上界
if (i2+size-1>n-1)
j2=n-1;  //若第2个子序列中不足size个元素,则置子序列2的上界j2=n-1
else j2=i2+size-1;        //否则有size个,置j2=i2+size-1
Merge(A,i1,j1,i2,j2);     //合并相邻两个子序列         i1=j2+1;                  //确定下一次合并第一个子序列的下界
}
size*=2;                     //元素个数扩大一倍
}
}

template <class T>
void AdjustDown(T A[], int r, int j)
{
int child=2*r+1; T temp=A[r];
while(child<=j) {
if((child<j)&&(A[child]<A[child+1])) child++;  //找两个孩子中较大的孩子
if (temp>= A[child]) break;
A[(child-1)/2]=A[child];
child=2*child+1;
}
A[(child-1)/2]=temp;
}

template <class T>
void HeapSort(T A[], int n)
{
for(int i=(n-2)/2; i>-1; i--)
AdjustDown(A,i,n-1);  //构造最大堆
for(int i=n-1; i>0; i--)
{
Swap(A[0],A[i]);                     //堆顶和堆底元素交换位置
AdjustDown(A,0,i-1);                 //将A[0]向下调整为堆
}
}

int main()
{
int a[SIZE];
time_t t0,t1;
/*SelectSort*/
for(int i=0;i<SIZE;i++)
{
a[i]=rand()%SIZE;
}

time(&t0);
SelectSort<int>(a,SIZE);
time(&t1);
cout<<"SelectSort:"<<t1-t0<<endl;

for(int i=0;i<SIZE;i++)
{
cout<<a[i]<<" ";
}
/*InsertSort*/
for(int i=0;i<SIZE;i++)
{
a[i]=rand()%SIZE;
}

time(&t0);
InsertSort<int>(a,SIZE);
time(&t1);
cout<<"InsertSort:"<<t1-t0<<endl;

for(int i=0;i<SIZE;i++)
{
cout<<a[i]<<" ";
}
/*BubbleSort*/
for(int i=0;i<SIZE;i++)
{
a[i]=rand()%SIZE;

}

time(&t0);
BubbleSort<int>(a,SIZE);
time(&t1);
cout<<"BubbleSort:"<<t1-t0<<endl;

for(int i=0;i<SIZE;i++)
{
cout<<a[i]<<" ";
}
/*QuickSort*/
for(int i=0;i<SIZE;i++)
{
a[i]=rand()%SIZE;
}

time(&t0);
QuickSort<int>(a,SIZE);
time(&t1);
cout<<"QuickSort:"<<t1-t0<<endl;

for(int i=0;i<SIZE;i++)
{
cout<<a[i]<<" ";
}

/*HeapSort*/
for(int i=0;i<SIZE;i++)
{
a[i]=rand()%SIZE;
}

time(&t0);
HeapSort<int>(a,SIZE);
time(&t1);
cout<<"HeapSort:"<<t1-t0<<endl;

/*MergeSort*/
for(int i=0;i<SIZE;i++)
{
a[i]=rand()%SIZE;
}
time(&t0);
MergeSort<int>(a,SIZE);
time(&t1);
cout<<"MergeSort:"<<t1-t0<<endl;

for(int i=0;i<SIZE;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: