实验要求:
①生成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函数就是用快速排序实现的