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


假设需要排序的数一共有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;	
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值