数据结构与算法实验:查找及排序

实验要求:
①生成100个在[200, 1000]之间的整数保存数组A中,以此数组元素作为关键字,采用希尔排序算法按非递减方式进行排序,给出操作的结果及相应的操作次数;
②生成200个在[200, 10000]之间的整数保存数组A中,以此数组元素作为关键字,采用快速排序算法按非递减方式进行排序,给出操作的结果及相应的操作次数;
③生成500个在[200, 10000]之间的整数保存数组A中,以此数组元素作为关键字,采用堆排序算法按非递减方式进行排序,给出操作的结果及相应的操作次数;
④ 主函数通过调用函数实现以上操作。

实验用随机数函数生成的关键字值,最好用时间做种子来生成,这样每次运行生成的数都不一样更加具有参考价值。

参数列表里面的compare和move两个指针地址的值是储存各个排列函数的比较次数和交换次数的,如果不想把函数列表写得那么长可以把那些变量设置为全局变量,这样就不需要传参也能变量里面的值。

实验代码如下:

#include <bits/stdc++.h>
using namespace std ;
// 希尔排序
void shellsort(int arr[] , int len , int* compare , int* move ) {
    int d = len/2 ;	// gap的值
    while ( d ){
       for (int x = 0 ; x < d ; x++) {	//对于gap所分的每一个组
	        for (int i = x+d ; i < len ; i += d) {      //进行插入排序
		    	int temp = arr[i];
		        int j ;
		        for (j = i-d ; j >= 0 && arr[j] > temp ; j = j - d){
		            arr[j+d] = arr[j] ;
		            (*move)++ ;
		            (*compare)++ ;
		        }
		        arr[j+d] = temp;
		        (*move)++ ; 
	        }
       }
       d = d / 2;//每次都将gap的值减半
    } 
}
// 快速排序 
void quicksort(int arr[] , int left , int right , int* compare , int* move )
{
    int temp ;
    int i = left , j = right ;	// left 和 right 分别为要比较的区域边界 
    if( left < right )
    {
        temp = arr[left] ;
        while( i != j )
        {
            while( j > i && arr[j] > temp ) --j , (*compare)++ ;//从右边扫描找到一个小于temp元素
            if( i < j )
            {
                arr[i] = arr[j];
            	(*move)++ ;
			    ++i ;
            }
            while( i < j && arr[i] < temp) ++i , (*compare)++ ;//从左边扫描,找到一个大于temp元素
            if( i < j )
            {
                arr[j] = arr[i] ;
             	(*move)++ ;
			    --j ;
            }
        }
        arr[i] = temp ;//temp放在最终位置
        (*move)++ ;
        quicksort( arr , left , i-1 , compare , move );  //对temp左边元素进行扫描
        quicksort( arr , i+1 , right , compare , move); //对temp右边元素进行扫描
    }
}

//    构成堆 (堆排序)
void heapadjust(int arr[], int parent, int len , int* compare , int* move )
{
    int child ;
    int temp ;

    for (temp = arr[parent]; 2 * parent + 1 < len; parent = child )	// 	parent = child 避免调整之后以 child 为父节点的子树不是堆 
    {
        child = 2 * parent + 1;

        if (child < len - 1 && arr[child + 1] > arr[child])
        {
            child++;
        }
        (*compare)++;
        if (temp < arr[child])
        {
            swap (arr[child] , arr[parent]);
            (*move) += 3 ;
        }
        else
            break;
    }
}
//    堆排序
void heapsort(int arr[], int len , int* compare , int* move )
{
    int i;
	// 把初始堆变成最大堆(需从最后一个非叶子结点开始调整)
    for (i = (len - 1) / 2; i >= 0; i--)
        heapadjust(arr, i, len , compare , move );
    
    for (i = len - 1; i > 0; i--)
    {
        swap(arr[0] , arr[i] );            //    每次将最大的数排在最后
        (*move) += 3;						//	swap函数执行一次移动3次 
        heapadjust(arr, 0, i , compare , move );                //    重新构成堆,将最大的数放在第一位
    }
}

int main()
{
	int i , j , n , m , shellcompare = 0 , shellmove = 0 , quickcompare = 0 , quickmove = 0 , heapcompare = 0 , heapmove = 0 ;// 比较次数和移动次数 
	int shellnum[105] , quicknum[205] , heapnum[505] ; // 分别存储希尔排序,快速排序,堆排序的关键字值
	
	srand((unsigned)time(NULL));
	for( i = 0 ; i < 100 ; i++ ){	// 开始生成随机数 
		shellnum[i] = 200 + rand()%801 ;
	}
	for( i = 0 ; i < 200 ; i++ ){	// 开始生成随机数
		quicknum[i] = 200 + rand()%9800 ;
	}  
	for( i = 0 ; i < 500 ; i++ ){	// 开始生成随机数
		heapnum[i] = 200 + rand()%9800 ;
	}
	
	cout << "希尔排序之前的排序为: " << endl ;
	for( i = 0 ; i < 100 ; i++ ){
    	printf("%4d ",shellnum[i]);
    	if( (i+1)%20 == 0 )		cout << endl ;
	}
	
	shellsort( shellnum , 100 , &shellcompare , &shellmove ) ;   //给出希尔排序操作的结果及相应的操作次数 
	
	cout << "希尔排序之后的排序为:" << endl ;
    for( int i = 0 ; i < 100 ; i++ ){
    	printf("%4d ", shellnum[i]) ;
    	if( (i+1)%20 == 0 )		cout << endl ;
	}
	cout << "此次希尔排序比较次数为:" << shellcompare << endl ;
	cout << "此次希尔排序移动次数为:" << shellmove << endl << endl ;
	
	
	cout << "快速排序之前的排序为: " << endl ;
	for( i = 0 ; i < 200 ; i++ ){
    	printf("%4d ",quicknum[i]);
    	if( (i+1)%20 == 0 )		cout << endl ;
	}
	
	quicksort( quicknum , 0 , 200-1 , &quickcompare , &quickmove ); 
		
	cout << "快速排序之后的排序为: " << endl ;
	for( int i = 0 ; i < 200 ; i++ ){
    	printf("%4d ", quicknum[i]) ;
    	if( (i+1)%20 == 0 )		cout << endl ;
	}
	cout << "此次快速排序比较次数为:" << quickcompare << endl ;
	cout << "此次快速排序移动次数为:" << quickmove << endl << endl ;
	
	
	cout << "堆排序之前的排序为: " << endl ;
	for( i = 0 ; i < 500 ; i++ ){
    	printf("%4d ", heapnum[i]);
    	if( (i+1)%20 == 0 )		cout << endl ;
	}
	
	heapsort( heapnum , 500 , &heapcompare , &heapmove ) ;
	
	cout << "堆排序之后的排序为: " << endl ;
	for( int i = 0 ; i < 500 ; i++ ){
    	printf("%4d ", heapnum[i]) ;
    	if( (i+1)%20 == 0 )		cout << endl ;
	}
	cout << "此次堆排序比较次数为:" << heapcompare << endl ;
	cout << "此次堆排序移动次数为:" << heapmove << endl << endl ;
	
	return 0 ;
}

其中stl中的sort函数就是用快速排序实现的

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值