BUPT2021秋季计算导论第十次实验

BUPT2021计算导论第十次实验

简单排序

实验7_9_简单排序 (100 分)
设计函数 void bubbleSort(int a[],int n);,实现对整型数组的排序。

输入第一行为一个整数n(0<n<=1000),代表待排序元素的个数。第二行是n个整数,每个整数都不会超过int型的存储范围,为待排序元素。

输出只有一行,为输入的n个待排序元素按从小到大排序后的结果。(建议采用起泡排序算法)

建议设计一个辅助函数:

函数功能:依次输出数组中各个元素,数与数之间用空格分开,最后一个数后没有空格而是换行符

参数说明:数组名,数组内元素个数

void outputData(int data[],int elementCount) ;

注:此题大家可以练习各种排序算法。

函数接口定义:
函数原型如下:
void bubbleSort(int a[],int n);
辅助函数原型:
void outputData(int data[],int elementCount) ;
其中 a 和 n 都是用户传入的参数。 n 是大于0且小于等于1000的整数,代表待排序元素的个数; a 是待排序数组。

辅助函数原型: 其中 data 和 elementCount 都是用户传入的参数。 elementCount 是大于0且小于等于1000的整数,代表元素的个数; data 是待输出的数组。

裁判测试程序样例:
设计了辅助函数后,函数被调用的例子如下:
#include<stdio.h>

void bubbleSort(int a[],int n);

//输出数组中所有元素
void outputData(int data[],int elementCount) ;

int main()
{
int n , i, num[10010] ;

scanf("%d",&n); 
for( i = 0 ; i < n ; i++ ) 
    scanf("%d",&num[i]) ;
bubbleSort(num,n) ; 
outputData(num,n) ;
return 0 ;

}

/* 请在这里填写答案 */
输入样例:
8
49 38 65 97 76 13 27 4
输出样例:
4 13 27 38 49 65 76 97

#include<stdio.h>

void bubbleSort(int a[],int n);
void outputData(int data[],int elementCount) ;

int main()
{
    int        n , i,    num[10010] ;

    scanf("%d",&n); 
    for( i = 0 ; i < n ; i++ ) 
        scanf("%d",&num[i]) ;
    bubbleSort(num,n) ; 
    outputData(num,n) ;
    return 0 ;
}

void bubbleSort(int a[], int n )
{
    int  i ;
    int temp ;
    for ( i = 0 ; i < n ; i++)
        {
            int j ;
            for ( j = i ; j< n-1 ; j++)
                {
                    if ( a[i]>a[j+1])
                        {
                            int temp ;
                            temp = a[j+1];
                            a[j+1] = a[i];
                            a[i] = temp  ;
                        }
                }
        }
    return ;
}
void outputData(int a[] , int n )
{
    int i ;
    for (i = 0 ;i < n-1 ; i++)
        {
            printf("%d ", a[i]);
        }
    printf("%d\n", a[i]);
    return ;
}

发子弹

实验7_10_发子弹 (100 分)
在某次实弹射击训练中,班长让战士们围成一圈发子弹。首先,班长给每个人发若干发子弹,然后按如下方法将每个战士手中的子弹进行调整:所有的战士检查自己手中的子弹数,如果子弹数为奇数,则向班长再要一颗。然后每个战士再同时将自己手中的子弹分一半给下一个战士(最后一个战士将手中的子弹分一半给第1个战士)。这种调整会一直进行下去,直到所有战士手中的子弹数相等为止。现请你写一个函数模拟这个调整的过程。

函数接口定义:
void distribute(int * bullets , int size , int number ) ;
其中 bullets 、 size 和 number 都是用户传入的参数。 bullets 为指向一个int 型数组的指针,该数组中依次存储着每个战士手中的子弹数,每次调整后该数组仍然依次存储着每个战士手中的子弹数 ; size 是战士的总数; number为调整的次数。函数没有返回值。

裁判测试程序样例:

#include<stdio.h>

#define LEN 100

//调整函数
void distribute(int * bullets , int size , int number ) ;

int main()
{
int bullets[LEN] ;
int n , m , i ;

scanf("%d" , &n ) ;    //读入战士总数 
for( i = 0 ; i < n ; i++ )
{
    scanf("%d" , &bullets[i] ) ;//读入每个战士手中初始的子弹数 
}
scanf("%d" , &m ) ;//读入调整的次数(m>0) 
distribute(bullets , n , m ) ;//调整 
for( i = 0 ; i < n - 1 ; i++ )//输出调整后结果 
{
    printf("%d " , bullets[i] ) ;
}
printf("%d\n" , bullets[i] ) ;

return 0;    

}

/* 请在这里填写答案 */
输入样例:
10
10 2 8 22 16 4 10 6 14 20
1
输出样例:
15 6 5 15 19 10 7 8 10 17

#include<stdio.h>

#define        LEN        100

void distribute(int * bullets , int size , int number ) ;

int main()
{
    int        bullets[LEN] ;
    int        n , m , i ;    

    scanf("%d" , &n ) ;    //读入战士总数 
    for( i = 0 ; i < n ; i++ )
    {
        scanf("%d" , &bullets[i] ) ;//读入每个战士手中初始的子弹数 
    }
    scanf("%d" , &m ) ;//读入调整的次数(m>0) 
    distribute(bullets , n , m ) ;//调整 
    for( i = 0 ; i < n - 1 ; i++ )//输出调整后结果 
    {
        printf("%d " , bullets[i] ) ;
    }
    printf("%d\n" , bullets[i] ) ;

    return 0;    
}

void distribute(int * bullets , int size , int number ) 
{
	int i ;
	int j ;
	int temp[size] ={ 0};
	for (i = 0; i< number; i++)
		{
			int count = 0;
			for ( j = 0 ;j < size ; j++)
				{
					if (*(bullets + j ) %2 != 0)
						{
							*(bullets + j ) = *(bullets + j) + 1;
							temp[count++] = *(bullets + j) ; 
						}
					else {
						temp[count++] = *(bullets + j) ; 
					}
				}
			for (j = 0; j< size ;j ++)
				{
					
					if ( j == 0)
						{
							*(bullets) = temp[0] /2 + temp[size -1 ]/2 ;
						}
						else {
							*(bullets + j) = temp [j] /2 + temp[j-1] /2 ; 
						}
					
				}
		
		}
	return ;
}
	

循环移位

实验7_11_循环移位 (100 分)
设计函数void shift(int *array , int num , int size ) ;,实现将整型数组内元素循环向左移若干位置。循环向左移位含义如下:

比如,原始数组a[0],a[1]…a[9]内元素依次为:1 2 3 4 5 6 7 8 9 10,循环向左移1位后,则a[0],a[1]…a[9]内元素依次为:2 3 4 5 6 7 8 9 10 1,循环向左移2位后,则a[0],a[1]…a[9]内元素依次为:3 4 5 6 7 8 9 10 1 2。依次类推。

函数接口定义:
void shift(int *array , int num , int size ) ;
其中 array 、 num和 size 都是用户传入的参数。 array 为指向原始数组的指针; num 为向左移的位数;size 为数组的大小。函数没有返回值。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

void shift(int *array , int num , int size ) ;

int main()
{
int i , n , p , array[100] ;

scanf(" %d%d" , &n , &p ) ;//测试用例保证0<p<n<=100
for( i = 0 ; i < n ; i++ )
    scanf( "%d" , &array[i] ) ;//测试用例保证所有输入可以用整型存储

shift( array , p , n ) ;//向左移p位
for( i = 0 ; i < n - 1 ; i++ )
    printf( "%d " , array[i] ) ;
printf( "%d\n" , array[i] ) ;
    
return 0;    

}

/* 请在这里填写答案 */
输入样例:
10 1
1 2 3 4 5 6 7 8 9 10
输出样例:
2 3 4 5 6 7 8 9 10 1

#include <stdio.h>
#include <stdlib.h>

void shift(int *array , int num , int size ) ;

int main()
{
    int        i , n , p , array[100] ;

    scanf(" %d%d" , &n , &p ) ;//测试用例保证0<p<n<=100
    for( i = 0 ; i < n ; i++ )
        scanf( "%d" , &array[i] ) ;//测试用例保证所有输入可以用整型存储

    shift( array , p , n ) ;//向左移p位
    for( i = 0 ; i < n - 1 ; i++ )
        printf( "%d " , array[i] ) ;
    printf( "%d\n" , array[i] ) ;

    return 0;    
}
void shift(int *array , int num , int size )
{
	int i ;
	int b[100] = { 0};
	for (i = 0 ; i < size ; i++)
		{
		   b[i] = *(array + i);
		   //printf("%d",b[i]); 
		}
	printf("\n");
	for ( i =0 ; i< size ; i++)
		{
			*(array + i) = b[i + num];
			if (i >size - num -1&& i <= size -1 )
				{
					*(array + i) = b[i + num - size];
				}
		}
}

插入排序

实验7_12_插入排序 (100 分)
设计函数 void InsertSort(int a[],int n); 该函数使用插入排序算法,将数组a的前n个元素按照升序的方式排序。

插入排序算法描述如下:

初始序列:49 38 65 97 76 13 27 49

将元素(38) 插入合适位置: [38 49] 65 97 76 13 27 49

将元素(65) 插入合适位置: [38 49 65] 97 76 13 27 49

将元素(97) 插入合适位置: [38 49 65 97] 76 13 27 49

将元素(76) 插入合适位置: [38 49 65 76 97] 13 27 49

将元素(13) 插入合适位置: [13 38 49 65 76 97] 27 49

将元素(27) 插入合适位置: [13 27 38 49 65 76 97] 49

将元素(49) 插入合适位置: [13 27 38 49 49 65 76 97]

输入与输出要求: 首先输入一个整数n(1<=n<=1000),代表待排序元素的个数。然后输入n个整数,每个整数不会超过int型的存储范围。

输出为n-1行,依次为1到n-1趟排序后数组内各个元素。每行输出的顺序为a[0]至a[n-1],数与数之间用空格分开,注意第n个数后没有空格而是换行符。

函数接口定义:
函数原型如下:
void InsertSort(int a[],int n);
其中 a 和 n 都是用户传入的参数。 a 为待排序数组; n 需排序的元素的个数。函数没有返回值。

裁判测试程序样例:
函数被调用的例子如下:
#include<stdio.h>

//插入排序(升序)
//参数说明:数组,数组中已有元素个数
void InsertSort(int a[],int n);

int main()
{
int n , i, num[1000] ;

scanf( "%d" , &n ); 
for( i = 0 ; i < n ; i++ ) 
    scanf( "%d", &num[i] ) ;
InsertSort( num , n ) ; 
return 0 ;

}

/* 请在这里填写答案 */
输入样例:
8
49 38 65 97 76 13 27 49
输出样例:
在这里给出相应的输出。例如:

38 49 65 97 76 13 27 49
38 49 65 97 76 13 27 49
38 49 65 97 76 13 27 49
38 49 65 76 97 13 27 49
13 38 49 65 76 97 27 49
13 27 38 49 65 76 97 49
13 27 38 49 49 65 76 97

#include<stdio.h>
void InsertSort(int a[],int n);

int main()
{
    int        n , i,    num[1000] ;

    scanf( "%d" , &n ); 
    for( i = 0 ; i < n ; i++ ) 
        scanf( "%d", &num[i] ) ;
    InsertSort( num , n ) ; 
    return 0 ;
}
void InsertSort(int a[],int n)
{
	int i ;
	int j ;
	for ( i= 1; i<n ; i++)
		{
			for ( j =0 ; j<i ;j ++)
				{
					if(a[j]>a[i])
						{
							int temp ;
							temp = a[i];
							a[i] = a[j];
							a[j] = temp ;
						}
				}
			int k ;
			for ( k =0 ;k < n-1 ; k++)
				{
					printf("%d ", a[k]);
				}
			printf("%d\n", a[k]);
		}
}

选择排序

实验7_13_选择排序 (100 分)
设计函数 void SelectSort(int a[],int n); 使用选择排序算法对数组a的前n个元素按照升序的方式排序。

选择排序算法描述如下: 从a[0]到a[n-1]这段元素中找最小元素a[min],a[0]和a[min]交换;接着,从a[1]到a[n -1]这段元素中找最小元素a[min],a[1]和a[min]交换;依次类推,直到从a[n-2]到a[n -1]这段元素中找最小元素a[min],a[n-2]和a[min]交换。

输入:首先输入一个整数n(1<n<=1000),代表待排序元素的个数。然后是n个整数,每个整数不会超过int型的存储范围

输出为n-1行,依次为1到n-1趟排序后数组内各个元素。每行输出的顺序为a[0]至a[n-1],数与数之间用空格分开,注意第n个数后没有空格而是换行符。

建议设计两个辅助函数:

函数功能:找数组中的最小值元素,并返回其下标

参数说明:数组名,查找起始位置下标,查找终止位置下标

int findMin(int data[], int startLoc, int endLoc) ;

函数功能:依次输出数组中各个元素,数与数之间用空格分开,最后一个数后没有空格而是换行符

参数说明:数组名,数组内元素个数

void outputData(int data[],int elementCount) ;

函数接口定义:
三个函数原型如下:

//选择排序(升序)
//参数说明:数组,数组中已有元素个数
void selectSort(int data[],int elementCount) ;

//函数功能:找数组中的最小值元素,并返回其下标
//参数说明:数组名,查找起始位置下标,查找终止位置下标
int findMin(int data[], int startLoc, int endLoc) ;

//输出数组中所有元素
//参数说明:数组,数组中已有元素个数
void outputData(int data[],int elementCount) ;
裁判测试程序样例:
函数被调用的例子如下:

#include<stdio.h>

//选择排序(升序)
//参数说明:数组,数组中已有元素个数
void selectSort(int data[],int elementCount) ;

//函数功能:找数组中的最小值元素,并返回其下标
//参数说明:数组名,查找起始位置下标,查找终止位置下标
int findMin(int data[], int startLoc, int endLoc) ;

//输出数组中所有元素
//参数说明:数组,数组中已有元素个数
void outputData(int data[],int elementCount) ;

int main()
{
int n , i, num[1010] ;

scanf("%d",&n); 
for( i = 0 ; i < n ; i++ ) 
    scanf("%d",&num[i]) ;
selectSort(num,n) ; 
return 0 ;

}

/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:

8
49 38 65 97 76 13 27 4
输出样例:
在这里给出相应的输出。例如:

4 38 65 97 76 13 27 49
4 13 65 97 76 38 27 49
4 13 27 97 76 38 65 49
4 13 27 38 76 97 65 49
4 13 27 38 49 97 65 76
4 13 27 38 49 65 97 76
4 13 27 38 49 65 76 97

#include<stdio.h>

//选择排序(升序) 
//参数说明:数组,数组中已有元素个数 
void selectSort(int data[],int elementCount) ;

//函数功能:找数组中的最小值元素,并返回其下标 
//参数说明:数组名,查找起始位置下标,查找终止位置下标
int findMin(int data[], int startLoc, int endLoc) ; 

//输出数组中所有元素 
//参数说明:数组,数组中已有元素个数 
void outputData(int data[],int elementCount) ;

int main()
{
    int        n , i,    num[1010] ;

    scanf("%d",&n); 
    for( i = 0 ; i < n ; i++ ) 
        scanf("%d",&num[i]) ;
    selectSort(num,n) ; 
    return 0 ;
}
void selectSort(int data[],int elementCount)
{
	int i ;
	for ( i = 0 ; i< elementCount -1 ; i++)
		{
			data[i] = findMin(data ,i , elementCount -1 );
			outputData(data, elementCount);
		}
}
int findMin(int data[], int startLoc, int endLoc)
{
	
	int i ;
	int min ;
	int temp ;
	temp = data[startLoc];
	min = data[startLoc];
	for(i = startLoc+1; i<= endLoc ; i++)
		{
			if(min > data[i])
				{
					min = data[i] ;
				}
		}
		//min找最小值 
		data[startLoc]  = min ; 
	    for(i = startLoc+1; i<= endLoc ; i++)
			{
				if(data[i] == data[startLoc])
				{
				   data[i] = temp ;
				}
			}
			
	return data[startLoc];	
}
void outputData(int data[],int elementCount) 
{
	int k ;
	for( k = 0; k < elementCount -1 ; k++)
		{
			printf("%d ", data[k]);
		}
	printf("%d\n", data[k]);n
}

二分查找

实验7_14_二分查找 (100 分)
设计函数 int BinarySearch(int a[],int n,int key);

利用二分查找算法,在升序排列的数组a的前n个元素中查找值为key的数组元素的下标。如果数组a中存在整数key,则返回下标;否则返回-1。假设数组a中的元素互不相同。

输入与输出要求:

首先输入两个整数n,m,分别代表数组a中元素的个数与需要查找的整数的个数,n(0<n<=2000000)与m(0<m<=100000)。然后分别输入n个整数和m个整数,分别代表存放在数组中的数以及要查找的数。

输出m个整数,分别为要查找的数在数组a中的下标,如果数组a中不存在某个数,则输出-1。数与数之间用空格分开,注意第n个数后没有空格而是换行符。

函数接口定义:
int BinarySearch(int a[],int n,int key) ;
其中 a 、 n和 key 都是用户传入的参数。 a被查找的数组; n 是数组长度; key 是要查找的元素。如果找到,则返回该元素在数组中的下标,否则返回-1。

裁判测试程序样例:
#include<stdio.h>

//函数功能:二分查找
//函数参数:分别为被查找的数组,数组长度,所查找的元素
//函数返回值:如果找到,则返回该元素在数组中的下标,否则返回-1
int BinarySearch(int a[],int n,int key) ;

int main()
{
int num[2000000] ; //这个数组比较大,如果在你的电脑中无法分配这么大的内存,请改小后测试。
int n , m, i;
int key ;

scanf("%d%d",&n,&m); 
for( i = 0 ; i < n ; i++ ) 
    scanf("%d",&num[i]) ;
    
for( i = 0 ; i < m ; i++ ) 
{
    scanf("%d",&key) ;
    printf("%d",BinarySearch(num,n,key)) ;
    if ( i != m - 1 ) printf(" ") ;
    else printf("\n") ;
}
return 0 ;

}

/* 请在这里填写答案 */
输入样例:
15
20
-293 -213 -23 0 1 5 11 23 56 67 87 273 999 2132 10000
-23 -99999 0 999 953 67 56 44 33 87 -293 23 11 273 -213 2132 10000 87654 1 5
输出样例:
2 -1 3 12 -1 9 8 -1 -1 10 0 7 6 11 1 13 14 -1 4 5

#include<stdio.h>

//函数功能:二分查找
//函数参数:分别为被查找的数组,数组长度,所查找的元素
//函数返回值:如果找到,则返回该元素在数组中的下标,否则返回-1 
int BinarySearch(int a[],int n,int key) ; 

int main()
{
    int    num[2000000] ; //这个数组比较大,如果在你的电脑中无法分配这么大的内存,请改小后测试。
    int        n , m, i;    
    int        key ;

    scanf("%d%d",&n,&m); 
    for( i = 0 ; i < n ; i++ ) 
        scanf("%d",&num[i]) ;

    for( i = 0 ; i < m ; i++ ) 
    {
        scanf("%d",&key) ;
        printf("%d",BinarySearch(num,n,key)) ;
        if ( i != m - 1 ) printf(" ") ;
        else printf("\n") ;
    }
    return 0 ;
}
int BinarySearch(int a[],int n,int key)
{
	int left = 0;
	int right = n-1 ;
	int i ;
	int mid;
	while(left <= right )
		{
			mid = (left + right) /2;
			if( key == a[(left+right)/2])
			  {
			  	return (left + right)/2 ;
			  }
			  else if ( key > a[(left+right)/2])
			          {
			          	left = mid +1 ;
					  }
					  else if (key < a[(left+right)/2])
					  	{
					  		right = mid -1  ;
						  }
						  
		}
	if(left > right)
	  return -1;
}

二分查找递归

实验7_15_二分查找递归实现 (100 分)
设计递归函数 int RecurBinarySearch( int a[] , int key , int left , int right ) ; 利用二分查找算法,在升序排列的数组中查找值为key的数组元素的下标。如果数组中存在整数key,则返回下标;否则返回-1。假设数组a中的元素互不相同。

输入与输出要求:

首先输入两个整数n,m,分别代表数组a中元素的个数与需要查找的整数的个数,n(0<n<=2000000)与m(0<m<=100000)。然后分别输入n个整数和m个整数,分别代表存放在数组中的数以及要查找的数。

输出为m个整数,分别为要查找的数在数组a中的下标,如果数组a中不存在某个数,则输出-1。数与数之间用空格分开,注意第m个数后没有空格而是换行符。

注意:此题要求递归求解,且算法为二分查找,否则不得分。

函数接口定义:
int RecurBinarySearch( int a[] , int key , int left , int right ) ;
其中 a 、 key 、left 和 right 都是用户传入的参数。 a 为元素升序排列的整型数组; key 待查找元素;left 和 right 分别为查找范围的左右边界。如果数组中存在整数 key,则返回下标;否则返回-1。

裁判测试程序样例:
#include<stdio.h>

#define MAXN 2000000

int RecurBinarySearch( int a[] , int key , int left , int right ) ;

int main()
{
int a[MAXN];//这个数组比较大,如果在你的电脑中无法分配这么大的内存,请改小后测试。
int n , m , i , key ;

scanf("%d %d",&n , &m );    
for( i = 0 ; i < n ; i++ )
    scanf("%d", &a[i]);
    
for( i =0 ; i < m ; i++ )
{
    scanf("%d",&key);
    printf( "%d" , RecurBinarySearch( a , key , 0 , n - 1 ) );
    if ( i != m - 1 ) printf(" ") ;
    else printf("\n") ; 
}

return 0;

}

/* 请在这里填写答案 */
输入样例:
15
20
-293 -213 -23 0 1 5 11 23 56 67 87 273 999 2132 10000
-23 -99999 0 999 953 67 56 44 33 87 -293 23 11 273 -213 2132 10000 87654 1 5
输出样例:
2 -1 3 12 -1 9 8 -1 -1 10 0 7 6 11 1 13 14 -1 4 5

#include<stdio.h>

#define MAXN 2000000

int RecurBinarySearch( int a[] , int key , int left , int right ) ;

int main()
{
    int        a[MAXN];//这个数组比较大,如果在你的电脑中无法分配这么大的内存,请改小后测试。
    int        n , m , i , key ;

    scanf("%d %d",&n , &m );    
    for( i = 0 ; i < n ; i++ )
        scanf("%d", &a[i]);

    for( i =0 ; i < m ; i++ )
    {
        scanf("%d",&key);
        printf( "%d" , RecurBinarySearch( a , key , 0 , n - 1 ) );
        if ( i != m - 1 ) printf(" ") ;
        else printf("\n") ; 
    }

    return 0;
}
int RecurBinarySearch( int a[] , int key , int left , int right )
{
	int mid ;
    mid = ( left + right) /2 ;
    if(left >right)
    	{
    		return -1 ;
		}
    if (key == a[mid])
    	{
    		return mid ;
		}
	    else if (key > a[mid])
	    	{
	    	    return RecurBinarySearch(a,key,mid+1 , right);
	        }
	    	else
			{
	    		return RecurBinarySearch(a, key ,left ,mid-1);
			}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

影不在遗忘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值