8种排序算法

// Temp.cpp : 定义控制台应用程序的入口点。
//

#include"stdafx.h"

#define BestInsertSortLength 16
#define Swap(a,b)  (a)^=(b)^=(a)^=(b); 

#include<fstream>
#include<iostream>
#include<time.h>
#include<windows.h>
#include<WinBase.h>
using namespace std;

 inline unsigned __int64 GetCPUTickCount()
{
	 _asm
	{
		rdtsc;
	}
}

//输出
void Output(int *& arr,int num,ofstream &cout)
{
	for(int i=0;i<num;i++)
	{
		cout<<arr[i]<<"  ";
	}
	cout<<endl;
}

//选择排序
void SelectSort(int * & arr,int left,int right)
{
	 
	for(int i=left;i<=right;i++)
	{
		int max=arr[left];
		int index=left;
		for(int j=left;j<=right-i;j++)
		{
			if(arr[j]>max)
			{
				index=j;
				max=arr[j];
			}
		}
		if(index!=right-i)Swap(arr[index],arr[right-i]);
	}

}
//插入排序
void InsertSort(int *&arr,int left,int right)
{
	for(int i=left;i<=right;i++)
	{
		int j=i-1;
		while(j>=0&&arr[j]>arr[j+1])
		{
			Swap(arr[j],arr[j+1]);
			j--;
		}
	}
}
//冒泡排序
void BubbleSort(int *&arr,int num)
{
	 
     for(int i=0;i<num;i++)
     {
     	bool flag=false;
             for(int j=0;j<num-i-1;j++)
             {
                     if(arr[j]>arr[j+1])
                     {
                           Swap(arr[j],arr[j+1]);
                           flag=true;             
                     }
             }
             if(flag==false)
             	return ;
     }
}
//快速排序
int Patition(int *&arr,int left,int right)
{
	 int piviotElement=arr[left];
	 int piviot=left;
	 int low=left+1;
	 int high=right;
	 while(low<high)
	 {
		 while(low<high&&arr[low]<piviotElement)
		 {
			 low++;
		 }
		 while(high>low&&arr[high]>piviotElement)
		 {
			 high--;
 		 }
		 if(low<high)
		 {
			Swap(arr[low],arr[high]);
			low++;
			high--;
		 }
		 else
		 {
			 break;
		 }
	 }
	 if(arr[low]>arr[piviot])
	 {
		 if(low-1!=piviot)Swap(arr[low-1],arr[piviot]);
		 return low-1;
	 }
	 else
	 {
		 if(low!=piviot)Swap(arr[low],arr[piviot]);
	 }
	 return low;
}
void QuickSort(int *&arr,int left,int right)
{
	if(left>=right)return;
    
	 int piviot=Patition(arr,left,right);
	 
	 QuickSort(arr,left,piviot-1);
	 QuickSort(arr,piviot+1,right);
}
/*
//归并排序
void Merge(int *&arr,int *& sav,int left,int right,int mid)
{
      
	 int i;
     for( i=left;i<=right;i++)
     {
        sav[i]=arr[i];        
     }
     
      i=left;
     int j=mid+1;
     int index=left;
     while(i<=mid&&j<=right)
     {
         if(sav[i]>sav[j])
         {
            arr[index++]=sav[j++];
             
         }
         else
         {
             arr[index++]=sav[i++];
         }                   
     }
     while(i<=mid)
     {
        arr[index++]=sav[i++];
     }
        
        while(j<=right)
        {
              arr[index++]=sav[j++];      
        }
          
}
void MergeSort(int *&arr,int *&sav,int left,int right)
{
     if(right-left<=0)return;
      
     int mid=(left+right)/2;
     MergeSort(arr,sav,left,mid);
     MergeSort(arr,sav,mid+1,right);
     Merge(arr,sav,left,right,mid);
}
*/
//改进的归并算法 
/*改进:
  1,n<=16时用插入排序
  2,通过一个变量来记录第几次做merge时,应该从哪个数组copy数据到哪个数组;从而减少A,B数组之间来回copy数据
  3,不用递归  即用迭代来替换递归
  */
  void Merge(int *&arr,int *& sav,int left,int right,int mid)
{
    //  if(right-left<=1)return;
	 if(right<mid)
	 {
		/* for(int i=left;i<=right;i++)
		 {
			 arr[i]=sav[i];
		 }*/
		 memcpy(arr+left,sav+left,sizeof(int)*(right-left+1));
		 return ;
	 }
	   
     int i=left;
     int j=mid;
     int index=left;
     while(i<mid&&j<=right)
     {
         if(sav[i]>sav[j])
         {
            arr[index++]=sav[j++];  
         }
         else
         {
             arr[index++]=sav[i++];
         }                   
     }
     while(i<mid)
     {
        arr[index++]=sav[i++];
     }
        
        while(j<=right)
        {
              arr[index++]=sav[j++];   
			 
        }
	 
}

void MergeSort(int *&arr,int left,int right)
{
	if(arr==NULL) return;
	if(right<=left)return; //空数组
		
	int index=left;
	
	while(index+BestInsertSortLength<=right)
	{
		InsertSort(arr,index,index+BestInsertSortLength);
		index=index+BestInsertSortLength+1;
	}
	InsertSort(arr,index,right);
	 
	
	int *sav=new int[right-left+1];
	int mergeNum=1;
	for(;; mergeNum++)
	{
		index=left;
		while(index+2*mergeNum*BestInsertSortLength+1<=right)
		{
			if(mergeNum%2==1)
			{
					Merge(sav,arr,index,index+2*mergeNum*BestInsertSortLength+1,index+mergeNum*BestInsertSortLength+1);
			}
			else
			{
				  Merge(arr,sav,index,index+2*mergeNum*BestInsertSortLength+1,index+mergeNum*BestInsertSortLength+1);
			}
			index=index+2*mergeNum*BestInsertSortLength+1;
		}
		  if(mergeNum%2==1)
			{
				 
					Merge(sav,arr,index,right,index+mergeNum*BestInsertSortLength+1);
			}
			else
			{
				  Merge(arr,sav,index,right,index+mergeNum*BestInsertSortLength+1);
			}
		  if(left+2*mergeNum*BestInsertSortLength+1>=right)
			  break;
	}
	if(mergeNum%2==1)
	{
			for(int i=left;i<=right;i++)
			{
				arr[i]=sav[i];
			}
	}
	 
}
//堆排序
void FixHeap(int *&arr,int start,int num) //调整堆
{
	
	int i=start;
	int j=2*i+1;
    
	while(j<=num)
	{
		if(j<num&&arr[j]<arr[j+1])
		{
				j++;
		}
		if(arr[i]<arr[j])
		{
			Swap(arr[i],arr[j]);
			i=j;
			j=2*i+1;
		}
		else
		{
			break;
		}
	}
	 
	 
}
void HeapSort(int *&arr,int num)
{
	if(num<=1)return ;
	
	for(int i=(num-2)/2;i>=0;i--)
	{
		 FixHeap(arr,i,num-1);
	}
	
	while(num-->=1)
	{       if(num!=0)Swap(arr[0],arr[num]);
			FixHeap(arr,0,num-1);
	}
}

//基数排序用到的数据

const int Barrel_Num=10;  //分为几个桶
int barrels[Barrel_Num];  //各个桶
struct Element            //暂时存放元素的静态链表
{
	int data;
	int next;
	Element()
	{
		next=-1;
	}
	int getDigit(int index) //得到data第index位的数字
	{
		int temp=data;
		for(int i=index;i>1;i--)
		{
			temp=temp/10;
		}
		return temp%10;
	}
};
//基数排序
//@param
//arr 待排序数组
//left 待排序数组的起始下标
//right 待排序数组的终止下标
//currentDepth 当前位 一开始为1
//maxDepth  最大位  由要排序数组中的最大元素的位数决定

void RadixSort(int *&arr,int left,int right,int currentDepth,int maxDepth)
{
	if(currentDepth>maxDepth)return;  //超过最大位 结束

	memset(barrels,-1,sizeof(int)*Barrel_Num);
	Element *ele=new Element[right-left+1];
	for(int i=right;i>=left;i--)  //倒着依次装入桶中
	{
		int j=right-i;
		ele[j].data=arr[i];
		int temp=ele[j].getDigit(currentDepth);
		if(barrels[temp]==-1)
		{
			barrels[temp]=j;
		}
		else
		{
			ele[j].next=barrels[temp];
			barrels[temp]=j;
		}
	}
	//顺序依次取出桶中的元素
	int count=left;
	for(int i=0;i<Barrel_Num;i++)
	{
		int temp=barrels[i];
		while(temp!=-1)
		{
			arr[count]=ele[temp].data;
			temp=ele[temp].next;
			count++;
		}
	}
	delete []ele;
	RadixSort(arr,left,right,currentDepth+1,maxDepth);
}
//希尔排序
void ShellSort(int * & arr,int num)
{
	int gap=num;
	do
	{
		gap=gap/3+1;
		for(int i=0;i<gap;i++)
		{
			for(int j=i+gap;j<num;j+=gap)
			{
				int k=j-gap;
				while(k>=0&&arr[k]>arr[k+gap])
				{
					Swap(arr[k],arr[k+gap]);
					k-=gap;
				}
			}
		}
	}while(gap>1);
}


int main()
{
	ofstream cout("output.txt");
	srand((unsigned int)time(0));
	 int n=rand()%5000+5000;
 
	int *arr =new int [n];
	int *forSort=new int[n];
  for(int i=0;i<n;i++)
  {
  	    forSort[i]=rand()%1000000;
  }
    memcpy(arr,forSort,sizeof(int)*n);
	cout<<"未排序:"<<endl;
	Output(arr,n,cout);
	 
	unsigned __int64 startTime;
	unsigned __int64 finishTime;

	 startTime=GetCPUTickCount();
   SelectSort(arr,0,n-1);
     finishTime=GetCPUTickCount();
   cout<<"选择排序:"<<endl;
   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
   Output(arr,n,cout);
    
   memcpy(arr,forSort,sizeof(int)*n);
   
   startTime=GetCPUTickCount();
   InsertSort(arr,0,n-1 );
   finishTime=GetCPUTickCount();
   
   cout<<"插入排序:"<<endl;
   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
   Output(arr,n,cout);
   
   memcpy(arr,forSort,sizeof(int)*n);
   
    startTime=GetCPUTickCount();
  BubbleSort(arr,n);
   finishTime=GetCPUTickCount();

  cout<<"冒泡排序:"<<endl;
  cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
  Output(arr,n,cout);
   
 	memcpy(arr,forSort,sizeof(int)*n);
 	
 	 startTime=GetCPUTickCount();
  MergeSort(arr,0,n-1);
 finishTime=GetCPUTickCount();
 
   cout<<"归并排序:"<<endl;
   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
   Output(arr,n,cout);
   memcpy(arr,forSort,sizeof(int)*n);
   
  startTime=GetCPUTickCount();
	QuickSort(arr,0,n-1);
	finishTime=GetCPUTickCount();
	
	cout<<"快速排序:"<<endl;
   cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
	 Output(arr,n,cout);
	 memcpy(arr,forSort,sizeof(int)*n);
	
	startTime=GetCPUTickCount(); 
	HeapSort(arr,n);
	finishTime=GetCPUTickCount();
	
	cout<<"堆排序:"<<endl;
  cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
	Output(arr,n,cout);
	 memcpy(arr,forSort,sizeof(int)*n);
     
     startTime=GetCPUTickCount(); 
    ShellSort(arr,n);
    finishTime=GetCPUTickCount();
    
    cout<<"希尔排序:"<<endl;
    cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
	Output(arr,n,cout); 

	startTime=GetCPUTickCount();
    RadixSort(arr,0,n-1,1,6);
	finishTime=GetCPUTickCount();
	cout<<"基数排序:"<<endl;
    cout<<"用时:"<<finishTime-startTime<<"个CPU周期"<<endl;
	Output(arr,n,cout); 
	 

    system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值