6-1 实验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
void bubbleSort(int a[],int n)
{
int tem,loc,i;
for(loc=n-1;loc>0;loc--)
{
for(i=0;i<loc;i++)
{
if(a[i]>a[i+1])
{
tem=a[i];
a[i]=a[i+1];
a[i+1]=tem;
}
}
}
}
void outputData(int data[],int elementCount)
{
int i;
for(i=0;i<elementCount-1;i++)
{
printf("%d ",data[i]);
}
printf("%d\n",data[elementCount-1]);
}
6-2 实验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
//思路一:设计辅助数组,当作中间变量使用
void distribute(int * bullets , int size , int number )
{
int TI,ti,half[size];
for(TI=1;TI<=number;TI++)
{
for(ti=0;ti<size;ti++)
{
if(bullets[ti]%2!=0)
{
bullets[ti]++;
}
half[ti]=bullets[ti]/2;
bullets[ti]/=2;
}
for(ti=1;ti<size;ti++)
{
bullets[ti]+=half[ti-1];
}
bullets[0]+=half[size-1];
}
}
//20220116思路二:不设计辅助数组,直接在这一个数组上完成各项操作
void distribute(int * bullets , int size , int number ){
int temp;
if (bullets[size-1]%2!=0)
bullets[size-1]++;
temp=bullets[size-1]/2;
bullets[size-1]=temp;
for (int i = size-2; i >= 0; --i) {
if (bullets[i]%2!=0)
bullets[i]++;
bullets[i]/=2;
bullets[i+1]+=bullets[i];
}
bullets[0]+=temp;
if (number>1)
distribute( bullets , size , number-1);
}
6-3 实验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
void InsertSort(int a[],int n)
{
int temp,k,i,flag,t;
for(k=1;k<n;k++)
{
temp=a[k];
for(i=0,flag=1;flag&&i<k;i++)
{
if(a[i]>=a[k])
{
flag=0;
for(t=k-1;t>=i;t--)
{
a[t+1]=a[t];
}
a[i]=temp;
}
}
for(i=0;i<n-1;i++)
{
printf("%d ",a[i]);
}
printf("%d\n",a[n-1]);
}
}
6-4 实验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
void shift(int *array , int num , int size )
{
int k,i,n,temp[num];
for(i=0;i<num;i++)
{
temp[i]=array[i];
}
for(i=0;i<size-num;i++)
{
array[i]=array[i+num];
}
for(i=0;i<num;i++)
{
array[size-num+i]=temp[i];
}
}
//20220116思路二:shift函数内,每次移动一位,再递归多次调用函数shift,实现多次循环移位
void shift(int *array , int num , int size ){
int temp;
array[0]=temp;
for (int i = 1; i < size; ++i) {
array[i-1]=array[i];
}
array[size-1]=temp;
if (num>1)
shift( array , num-1 , size ) ;
}
6-5 实验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
void outputData(int data[],int elementCount)
{
int i,a;
for(i=0;i<elementCount-1;i++)
{
printf("%d ",data[i]);
}
printf("%d\n",data[elementCount-1]);
}
int findMin(int data[], int stl, int edl)
{
int i,min,n,flag;
min=data[stl];
flag=stl;
for(i=stl+1;i<edl;i++)
{
if(data[i]<min)
{
min=data[i];
flag=i;
}
}
return flag;
}
void selectSort(int data[],int elementCount)
{
int i,exc,n,tem;
for(i=0;i<elementCount-1;i++)
{
exc=findMin(data, i , elementCount);
tem=data[i];
data[i]=data[exc];
data[exc]=tem;
outputData(data,elementCount);
}
}
6-6 实验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
int BinarySearch(int a[],int n,int key)
{
int middle,left,right;
left=0;
right=n-1;
middle=(left+right)/2;
while(left<=right&&a[middle]!=key)
{
if(key<a[middle])
{
right=middle-1;
}
else
{
left=middle+1;
}
middle=(left+right)/2;
}
if(left>right)
return -1;
else
return middle;
}
//20220122干净、简洁
int BinarySearch(int a[],int n,int key){
int left=0,right=n-1,middle;
while (left < right){
middle=(left+right)/2;//放在while里面的第一句,避免了重复
if (a[middle]>key)
right=middle-1;
else if (a[middle]<key)
left=middle+1;
else return a[middle];//既不大于,又不小于,只能等于,所以return即可
}
return -1;跳出了while,却没能return一个数字回去,说明没有找到,所以return -1了
}
6-7 实验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
//标准的递归函数:最外层是if-else结构
int RecurBinarySearch( int a[] , int key , int left , int right )
{
int middle;
middle=(left+right)/2;
if(left>right||a[middle]==key)
{
if(a[middle]==key)
{
return middle;
}
else
{
return -1;
}
}
else
{
if(key<a[middle])
{
right=middle-1;
}
else
{
left=middle+1;
}
middle=(left+right)/2;
RecurBinarySearch( a , key , left , right );
}
}
//20220122更干净、简洁的代码
int RecurBinarySearch(int a[] , int key , int left , int right )
{
if(right<left)
return -1;
int middle=(right+left)/2;
if(a[middle]==key)
return middle;
else if(a[middle]>key)
return RecurBinarySearch(a,key,left,middle-1);
else
return RecurBinarySearch(a,key,middle+1,right);
}