选择 插入 冒泡 希尔

/* 选择排序*/
#include<iostream>
#include<algorithm>
#include"SortTestHelper.h"
using namespace std;

template<typename T>
void selectionSort(T arr[],int n){
	for(int i=0;i<n;i++){
		int min=i;
		for(int j=i+1;j<n;j++){
			if(arr[j]<arr[min]){
				 min=j;
			}
		}
			swap(arr[i],arr[min]);

	}
}

//对正常插入排序算法的改进,思路一样 但是减少赋值的次数 传统方式一次交换就是三次赋值,这里有一次赋值就行    改进后由于减少了赋值次数 同时还插入排序可以提前终止内层循环,所以用的时间小于选择排序 
template<typename T>
void insertionSort(T arr[],int n){
	for (int i=1;i<n;i++){
		T e=arr[i];
		int j;//保存元素e应该插入的位置 

		for ( j=i;j>0&&arr[j-1]>e;j--){
			arr[j]=arr[j-1];
		}
		arr[j]=e;
	}
} 

//冒泡排序O(n方) 
template<typename T>
void gudugudu(T arr[],int n){
	for(int i=n-1;i>0;i--){
		for(int j=0;j<i;j++){
			if(arr[j]>arr[j+1]){
				swap(arr[j],arr[j+1]);
		}
	}
}
}

//希尔排序
const int INCRGAP=3;

template<typename T>
void shellsort(T arr[],int n){
	int insertNum=0;
	int gap=n/INCRGAP+1; // 步长初始化,注意如果当len<INCRGAP时,gap为0,所以为了保证进入循环,gap至少为1!!!
	while(gap){
		for(int i=gap;i<n;++i){
			insertNum=arr[i];
			int j=i;
			while(j>=gap&&insertNum<arr[j-gap]){
				arr[j]=arr[j-gap];
				j-=gap;
			}
			arr[j]=insertNum;
		}
		gap=gap/INCRGAP;
	}
} 


int main(){ 
	int n=10;
	int *arr=SortTestHelper::generateRandomArray(n,0,n);
	int *arr2=SortTestHelper::copyIntArray(arr,n);
	
	//近乎有序的数组 插入排序远远快于选择排序 
	int *arr3=SortTestHelper::generateNearlyOrderedArray(n,100);
	int *arr4=SortTestHelper::copyIntArray(arr3,n);
//	selectionSort(arr,n);
//	SortTestHelper::printArray(arr,n);

//	gudugudu(arr,n);
//	SortTestHelper::printArray(arr,n);

//	SortTestHelper::testSort("selectionSort",selectionSort,arr,n);
//	SortTestHelper::testSort("insertionSort",insertionSort,arr2,n);

//	SortTestHelper::testSort("selectionSort",selectionSort,arr3,n);
//	SortTestHelper::testSort("insertionSort",insertionSort,arr4,n);

//	SortTestHelper::testSort("insertionSort",insertionSort,arr3,n);
//	SortTestHelper::testSort("gudugudu",gudugudu,arr4,n);
	shellsort(arr,n); 
	SortTestHelper::printArray(arr,n);

	
	delete[] arr;
	delete[] arr2;
	delete[] arr3;
	delete[] arr4;
	system("Pause");
		return 0;
}
/* 随机生成范围数组的方法 封装成为了SortTestHelper.h文件  方便引用*/
#include<iostream>
#include<ctime>
#include<cassert>
using namespace std;
namespace SortTestHelper{
	//随机生成有n个元素的随机数组,每个元素的随机范围为[rangeL,rangeR] 
	int* generateRandomArray(int n,int rangeL,int rangeR){
		assert(rangeL<=rangeR);
		int* arr=new int[n];
		srand(time(NULL));//随机种子 
		for(int i=0;i<n;i++)
			arr[i]=rand()%(rangeR-rangeL+1)+rangeL;//闭区间控制随机数范围 
		return arr;
	}
	
	//生成近乎有序的随机数组 先生成全部有序的 然后随机交换几个元素的位置 
	 int* generateNearlyOrderedArray(int n,int swapTimes){
	 	int *arr=new int[n];
	 	for(int i=0;i<n;i++){
	 		arr[i]=i;
		 }
		 srand(time(NULL));
		 for(int i=0;i<swapTimes;i++){
		 	int posx=rand()%n;
		 	int posy=rand()%n;
		 	swap(arr[posx],arr[posy]);
		 }
		 return arr;
	 }
	//输出 
	template<typename T>
	void printArray(T arr[],int n){
		for(int i=0;i<n;i++)
			cout<<arr[i]<<" ";
		cout<<endl; 
		return ;
	}
	//检验排序是否正确
	template<typename T>
	bool isSorted(T arr[],int n){
		for(int i=0;i<n-1;i++)
			if(arr[i]>arr[i+1])
				return false;
		return true;
	} 
	//效率时间判断 
	template<typename T>
	void testSort(string sortName,void(*sort)(T[],int),T arr[],int n){// 第一个参数是排序的名字 第二个是传入的函数指针  第三个和第四个是传入的测试用例 
		clock_t startTime=clock();//clock()是时钟周期 
		sort(arr,n);
		clock_t endTime=clock();
		assert(isSorted(arr,n));
		cout<<sortName<<":"<<double(endTime-startTime)/CLOCKS_PER_SEC<<"s"<<endl;// CLOCKS_PER_SEC是标准库中每秒钟有几个时钟周期 		
		return; 
}
	//拷贝一个数组 
	int*  copyIntArray(int a[],int n){
		int* arr=new int[n];
		copy(a,a+n,arr);
		return arr;
	} 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值