• 各种排序算法练习


    最近忙着准备找工作,把之前写的排序算法整理下,写到一起,方便以后用,废话不说,直接上代码;

    #include<iostream>
    #include<time.h>
    using namespace std;
    #define N 100
    //#define SWAP(x,y){int t;t=x;x=y;y=t;}
    #define SWAP(x,y) {x=x^y;y=x^y;x=x^y;}
    //基数排序
    void radixsort(int data[], int n) 
    {
    	//辅助函数,求数据的最大位数
    	int d = 1; //保存最大的位数
        int p = 10;
        for(int i = 0; i < n; ++i)
        {
            while(data[i] >= p)
            {
                p *= 10;
                ++d;
            }
        }
    
    	//基数排序
        int *tmp = new int[n];
        int *count = new int[10]; //计数器
        int i, j, k;
        int radix = 1;
        for(i = 1; i <= d; i++) //进行d次排序
        {
            for(j = 0; j < 10; j++)
                count[j] = 0; //每次分配前清空计数器
            for(j = 0; j < n; j++)
            {
                k = (data[j] / radix) % 10; //统计每个桶中的记录数
                count[k]++;
            }
            for(j = 1; j < 10; j++)
                count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
            for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
            {
                k = (data[j] / radix) % 10;
                tmp[count[k] - 1] = data[j];
                count[k]--;
            }
            for(j = 0; j < n; j++) //将临时数组的内容复制到data中
                data[j] = tmp[j];
            radix = radix * 10;
        }
        delete[]tmp;
        delete[]count;
    }
    //shell排序,改进的插入排序
    int shellsort(int *number)
    {
    	for(int group=N/2;group>0;group/=2)
    	{
    		for(int i=group;i<N;i++)//每一个都循环,所以下面每次只交换一次
    		{
    			for(int j=i-group;j>=0&&(number[j]>number[j+group]);j-=group)//每次只能交换一次,交换多了就不对了
    			{
    				SWAP(number[j],number[j+group]);
    			}
    		}
    	}
    	return 0;
    }
    //插入排序
    int insort(int *number)
    {
    	/*int temp;
    	for(int i=N-2;i>=0;i--)//从大到小循环进行排序
    	{
    	temp=number[i];
    	int j=i+1;
    	while(temp>number[j])
    	{
    	number[j-1]=number[j];
    	j++;
    	if(j==N)
    	break;
    	}
    	number[j-1]=temp;
    	}*/
    	int temp,j;
    	for(int i=1;i<N;i++)//从小到大循环进行排序
    	{
    		temp=number[i];
    		for(j=i;j>0;j--)
    		{
    			if(number[j-1]>temp)
    			{
    				number[j]=number[j-1];
    			}
    			else
    			{
    				break;
    			}
    		}
    		number[j]=temp;
    	}
    	return 0;
    }
    //heap算法,堆排序,改进的选择排序
    int heapsort(int *number)
    {
    	//建立排序堆积树
    	int heap[N+1]={-1111},child,parent;
    	for(int i=1;i<=N;i++)
    	{
    		heap[i]=number[i-1];
    		child=i;
    		parent=i/2;
    		while(heap[child]<heap[parent]&&child>=2)//子树比根小并且有子树
    		{
    			SWAP(heap[child],heap[parent]);
    			child=parent;
    			parent=child/2;
    		}
    	}
    	//堆排序
    	int n=N;
    	while(n>1)
    	{
    		number[N-n]=heap[1];
    		SWAP(heap[1],heap[n]);
    		n--;
    		parent=1;
    		child=2*parent;
    		while(child<=n)
    		{
    			if(child<n&&heap[child]>heap[child+1])//有两个子树并右子树较小或
    				child++;
    			if(heap[parent]<=heap[child])//根比子树小
    				break;
    			SWAP(heap[parent],heap[child]);
    			parent=child;
    			child=2*parent;
    		}
    	}
    	number[N-1]=heap[1];
    	return 0;
    }
    //选择排序
    int selsort(int *number)
    {
    	int temp;
    	for(int i=0;i<N;i++)
    	{
    		int min=9999;
    		for(int j=i;j<N;j++)
    		{
    			if(min>number[j])
    			{
    				min=number[j];
    				temp=j;
    			}
    		}
    		number[temp]=number[i];
    		number[i]=min;
    	}
    	return 0;
    }
    //shaker排序,改进的冒泡排序
    int shakersort(int *number)
    {
    	int left=0,right=N-1,i;
    	int shift=left;
    	while(left<right)
    	{
    		for(i=left;i<right;i++)
    		{
    			if(number[i]>number[i+1])
    			{
    				SWAP(number[i],number[i+1]);
    				shift=i;
    			}
    		}
    		right=shift;
    		for(i=right;i>left;i--)
    		{
    			if(number[i]<number[i-1])
    			{
    				/*temp=number[i];
    				number[i]=number[i-1];
    				number[i-1]=temp;*/
    				SWAP(number[i],number[i-1]);
    				shift=i;
    			}
    		}
    		left=shift;
    	}
    	return 0;
    }
    //冒泡排序
    int bubsort(int *number)
    {
    	//int temp;
    	for(int i=0;i<N-1;i++)
    	{
    		for(int j=0;j<N-i-1;j++)
    		{
    			if(number[j]>number[j+1])
    			{
    				SWAP(number[j],number[j+1]);
    			}
    		}
    	}
    	return 0;
    }
    //快速排序1(最左为轴)
    void quicksort1(int *number,int left,int right)
    {
    	int s,i,j;
    	if(left<right)
    	{
    		s=number[left],i=left,j=right+1;
    		while(1)
    		{
    			while(i+1<right+1&&number[++i]<s)   ;
    			while(j-1>left-1&&number[--j]>s)  ;
    			if(i>=j)
    				break;
    			SWAP(number[i],number[j]);
    		}
    		number[left]=number[j];
    		number[j]=s;
    		quicksort1(number,left,j-1);
    		quicksort1(number,j+1,right);
    	}
    }
    //快速排序2(中间为轴)
    void quicksort2(int *number,int left,int right)
    {
    	int i,j,s;
    	if(left<right)
    	{
    		s=number[(left+right)/2],j=right+1,i=left-1;
    		while(1)
    		{
    			while(number[++i]<s)  ;
    			while(number[--j]>s)  ;
    			if(i>=j)
    				break;
    			SWAP(number[i],number[j]);
    		}
    		quicksort2(number,left,i-1);
    		quicksort2(number,j+1,right);
    	}
    }
    //算法导论书
    void quicksort3(int *number,int left,int right)
    {
    	int i,j,s,q;
    	if(left<right)
    	{
    		s=number[right];
    		i=left-1;
    		for(j=left;j<right;j++)
    		{
    			if(number[j]<=s)//当两个数一样的时候交换后为0
    			{
    				i++;
    				if(number[i]!=number[j])
    				//cout<<number[i]<<' '<<number[j]<<endl;
    				SWAP(number[i],number[j]);
    				//cout<<number[i]<<' '<<number[j]<<endl;
    			}
    		}
    		if(number[i+1]!=number[right])
    		SWAP(number[i+1],number[right]);
    		q=i+1;
    		quicksort3(number,left,q-1);
    		quicksort3(number,q+1,right);
    	}
    }
    //归并排序
    int mergeSort(int *data, int p, int r)  
    {  
    	int q;  
    	int n1, n2, i, j, k; 
    	if(p < r) //只有一个或无记录时不须排序   
    	{  
    		q = (int)((p+r)/2);      //将data数组分成两半     
    		mergeSort(data, p, q);   //递归拆分左数组  
    		mergeSort(data, q+1, r); //递归拆分右数组   
    
    		 //*************************合并数组
    		int *left=NULL, *right=NULL;  
    
    		n1 = q-p+1;   
    		n2 = r-q;  
    
    		left = (int *)malloc(sizeof(int)*(n1));   
    		right = (int *)malloc(sizeof(int)*(n2));  
    		//检查是否分配成功
    		if(left==NULL||right==NULL){
    			cout<<"归并排序分配内存错误!!!"<<endl;
    			return 0;
    		}
    		for(i=0; i<n1; i++)  //对左数组赋值  
    			left[i] = data[p+i];  
    		for(j=0; j<n2; j++)  //对右数组赋值  
    			right[j] = data[q+1+j];  
    
    		i = j = 0;   
    		k = p;  
    		while(i<n1 && j<n2) //将数组元素值两两比较,并合并到data数组  
    		{  
    			if(left[i] <= right[j])  
    				data[k++] = left[i++];  
    			else  
    				data[k++] = right[j++];  
    		}  
    
    		for(; i<n1; i++) //如果左数组有元素剩余,则将剩余元素合并到data数组  
    			data[k++] = left[i];  
    		for(; j<n2; j++) //如果右数组有元素剩余,则将剩余元素合并到data数组  
    			data[k++] = right[j];  
    		free(left); 
    		free(right); 
    		left=NULL;
    		right=NULL;
    		//当不需要再使用申请的内存时,记得释放;
    		//释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。 
    	}
    	return 0;
    }      
    int selectag()
    {
    	cout<<"输入0为退出,"<<endl
    		<<"输入1为冒泡排序,"<<endl
    		<<"输入2为选择排序,"<<endl
    		<<"输入3为插入排序,"<<endl
    		<<"输入4为希尔排序(改进的插入排序),"<<endl
    		<<"输入5为Shaker排序(改进的冒泡排序),"<<endl
    		<<"输入6为heap(堆)排序(改进的选择排序),"<<endl
    		<<"输入7为快速排序1(最左为轴),"<<endl
    		<<"输入8为快速排序2(中间为轴),"<<endl
    		<<"输入9为快速排序3(算法导论),"<<endl
    		<<"输入10为归并排序,"<<endl
    		<<"输入11为基数排序,"<<endl
    		<<"请选择排序算法:";
    	return 0;
    }
    int creatlist(int *number)
    {
    	int j,temp;
    	for(int i=0;i<N;i++)//随机生成1到N的数组
    	{
    		j=rand()%N;
    		temp=number[i];
    		number[i]=number[j];
    		number[j]=temp;
    	}
    	cout<<"排序前:"<<endl;
    	for(int i=0;i<N;i++)
    	{
    		cout<<number[i];
    		if(i<N-1)
    			cout<<"->";
    	}
    	cout<<endl;
    	return 0;
    }
    int main()
    {
    	clock_t start, finish;//开始结束时间 
    	double duration; //耗时
    	int number[N];
    	for(int i=0;i<N;i++)
    		number[i]=i;
    	srand((unsigned)time(NULL));
    	selectag();
    	int in=1,sortstatus=1;//sortstatus为是否进行了排序
    	char end;//是否退出循环
    	int inright=1;//输入正确
    	while(in!=0)
    	{
    		sortstatus=1;
    		while(inright)
    		{
    			cin.clear();//重置错误输入
    			cin.sync();//清空缓冲区  不然会出现无限循环
    			cin>>in;
    			if(!cin.fail())//如果输入不匹配,fail()会返回真
    			{
    				inright=0;
    			}
    			else
    			{
    				cout<<"**********************输入有误,不是int类型,请输入int数字:";
    				selectag();
    			}
    		}
    		start = clock(); //开始计时
    		switch(in)
    		{
    		case 0:
    			cout<<"**********************确认退出???(y/n)**********************"<<endl;
    			cin.clear();
    			cin>>end;
    			switch(end)
    			{
    			case 'y':case 'Y':
    				//这里退出,所以不用selectag();
    				break;
    			case 'n':case 'N':
    				selectag();
    				inright=1;//重新进行输入检测
    				sortstatus=0;//这次没有进行排序
    				in=9999;
    				break;
    			}
    			break;
    		case 1:
    			creatlist(number);
    			bubsort(number);
    			cout<<"冒泡排序:"<<endl;
    			break;
    		case 2:
    			creatlist(number);
    			selsort(number);
    			cout<<"选择排序:"<<endl;
    			break;
    		case 3:
    			creatlist(number);
    			insort(number);
    			cout<<"插入排序:"<<endl;
    			break;
    		case 4:
    			creatlist(number);
    			shellsort(number);
    			cout<<"希尔排序(改进的插入排序):"<<endl;
    			break;
    		case 5:
    			creatlist(number);
    			shakersort(number);
    			cout<<"Shaker排序(改进的冒泡排序):"<<endl;
    			break;
    		case 6:
    			creatlist(number);
    			heapsort(number);
    			cout<<"heap(堆)排序(改进的选择排序):"<<endl;
    			break;
    		case 7:
    			creatlist(number);
    			quicksort1(number,0,N-1);
    			cout<<"快速排序1(最左为轴):"<<endl;
    			break;
    		case 8:
    			creatlist(number);
    			quicksort2(number,0,N-1);
    			cout<<"快速排序2(中间为轴):"<<endl;
    			break;
    		case 9:
    			creatlist(number);
    			quicksort3(number,0,N-1);
    			cout<<"快速排序3(算法导论):"<<endl;
    			break;
    		case 10:
    			creatlist(number);
    			mergeSort(number,0,N-1);
    			cout<<"归并排序:"<<endl;
    			break;
    		case 11:
    			creatlist(number);
    			radixsort(number,N);
    			cout<<"基数排序:"<<endl;
    			break;
    		default:
    			sortstatus=0;
    			inright=1;
    			cout<<"**********************输入有误,请输入正确的数字!!!**********************"<<endl;
    			selectag();
    			break;
    		}
    		finish = clock(); //结束计时
    		duration=(double)(finish-start)/CLOCKS_PER_SEC;
    		cout<<"本算法总耗时"<<duration<<endl;
    		if(in!=0&&sortstatus)
    		{
    			for(int i=0;i<N;i++)
    			{
    				cout<<number[i];
    				if(i<N-1)
    					cout<<"->";
    			}
    			cout<<endl;
    			selectag();
    			inright=1;
    		}
    	}
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    jQuery.fly插件实现添加购物车抛物线效果
    jQuery 实现前端模糊匹配与首字母搜索
    Java生成微信二维码及logo二维码
    Map 与 JavaBean 的相互装换
    从零写Java Web框架——请求的处理DispatcherServlet
    从零写Java Web框架——实现Ioc依赖注入
    记一次校招面试
    使用DbUtils对JDBC封装实现面向实体查询
    HTTP Status 500 PWC6188 jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
    【插件】百度编译器ueditor插入视频的时候。在预览的窗口提示 “输入的视频地址有误,请检查后再试!
  • 原文地址:https://www.cnblogs.com/jhmu0613/p/6780741.html
Copyright © 2020-2023  润新知