排序和查找

一、排序算法

排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程。

排序的分类:

(1)内部排序:指将需要处理的所有数据都加载到内部存储器(内存)中进行排序。

(2)外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。

冒泡排序

(1)冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
(2)因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志 flag 判断元素是否进行过交换。从而减少不必要的比较。

冒泡排序实例

我们将五个无序的数:{3,9,-1,10,-2}使用冒泡排序法将其排成一个从小到大的有序数列。

#include<stdio.h>

//冒泡排序的函数
void bubbleSort(int arr[],int arrLen){
	//用 for 循环,循环比较排序
	int i,j;
	int temp;//临时变量
	for(i=0;i<arrLen-1;i++){
		for(j=0;j<arrLen-i-1;j++){
			//如果前面的一个数较大就交换
			if(arr[j]>arr[j+1]){
				temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
			} 
		}
	} 
}
void main(){
	int arr[]={3,9,-1,10,-2,-11};
	int arrLen=sizeof(arr)/sizeof(int);//计算得到数组元素的个数 
	int i;
	bubbleSort(arr,arrLen);//默认是地址传递 
	printf("\n排序后:\n"); 
	for(i=0;i<arrLen;i++){
		printf(" %d",arr[i]);
	} 
} 

在这里插入图片描述

问题升级,用键盘输入n个数,使用冒泡排序法将其排成一个从小到大的有序数列。

#include<stdio.h>

//冒泡排序的函数
void bubbleSort(int arr[],int n){
	//用 for 循环,循环比较排序
	int i,j;
	int temp;//临时变量
	for(i=0;i<n-1;i++){
		for(j=0;j<n-i-1;j++){
			//如果前面的一个数较大就交换
			if(arr[j]>arr[j+1]){
				temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
			} 
		}
	} 
}
void main(){
	printf("请输入数组的元素个数:");
	int n;
	scanf("%d",&n);
	printf("请输入数组的%d个元素:",n);
	int arr[n];
	int i;
	for(i=0;i<=n;i++){//循环输入
	    if(i<n){
            scanf("%d",&arr[i]);
        }
        else{//输入第n个数结束循环
        	break;
		}  
    }
	bubbleSort(arr,n);//默认是地址传递 
	printf("\n排序后:\n"); 
	int j;
	for(j=0;j<n;j++){
		printf(" %d",arr[j]);
	} 
} 

在这里插入图片描述

二、查找

在C中,我们常用的查找有两种:
(1)顺序查找
(2)二分查找

案例演示

顺序查找:有一个数列{23,1,34,89,101}猜数游戏:从键盘中任意输入一个数,判断数列中是否包含该数。

要求:如果找到了,就提示 找到了,并给出下标,找不到提示 没有。
思路:创建数组,输入一个元素,遍历数组,如果相等就输出找到了和它的下标。

#include<stdio.h>

int seqSearch(int arr[],int arrLen,int val){
	int i;
	for(i=0;i<arrLen;i++){
		if(arr[i]==val){
			return i;
		}
	}
	//如果在 for 循环中,没有返回return,说明没有找到
	return -1; 
}

void main(){
	int n;//要找的元素 
	scanf("%d",&n);
	int arr[]={23,1,34,89,101};
	int arrLen=sizeof(arr)/sizeof(int);
	int index=seqSearch(arr,arrLen,n);
	if(index != -1){
		printf("找到了 下标为:%d",index);
	} 
	else{
		printf("没有");
	}
}

输入101
在这里插入图片描述
输入102
在这里插入图片描述

二分查找:请对一个有序数组进行二分查找{1,8,10,89,1000,1234},输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。

二分查找的前提是该数组是一个有序数组。

  1. 思路分析:比如我们要查找的数是findVal。
  2. 先找到数组中间这个数 midVal,和findVal比较。
  3. 如果midVal > findVal 说明,应该在midVal的左边查找。
  4. 如果midVal < findVal 说明,应该在midVal 的右边查找。
  5. 如果midVal == findVal,说明找到。
//二分查找的前提是该数组是一个有序数组
// binarySearch 定义的二分查找函数名 
#include<stdio.h>
int binarySearch(int arr[],int leftIndex,int rightIndex,int findVal){
	//先找中间值 midVal
	int midIndex =(leftIndex + rightIndex)/2;
	int midVal = arr[midIndex];
	//如果 leftIndex > rightIndex, 说明这个数组比过,没有找到 
	
	if(leftIndex > rightIndex){
		return -1;
	}
	if(midVal > findVal){
		binarySearch(arr,leftIndex,midIndex-1,findVal);
	}
	
	else if(midVal < findVal){
	 	binarySearch(arr,midIndex+1,rightIndex,findVal);
	}
	else{
		return midIndex;
	}
}
 
void main(){
	int arr[]={1,8,10,89,1000,1234};
	int arrLen=sizeof(arr)/sizeof(int);
	int n;
	scanf("%d",&n);
	int index=binarySearch(arr,0,arrLen-1,n);
	if(index !=-1){
		printf("找到了 下标为:%d",index);
	}
	else{
		printf("没有"); 
	}
} 

输入1000
在这里插入图片描述
输入500
在这里插入图片描述

三、多维数组

二维数组:

案例1:请用二维数组输出如下图形

0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0

使用方式1:先定义在初始化

语法:类型数组名[大小][大小];
比如: int a[2][3];

二维数组在内存的存在形式,各个元素的地址是连续分布的,即在前一个元素基础上+4。

#include<stdio.h>

void main(){
	int a[4][6];//表示一个4行6列的二维数组 
	int i,j;
	//全部初始化为0 
	//不初始化,全是分配的垃圾值 
	for(i=0;i<4;i++){
		for(j=0;j<6;j++){
			a[i][j]=0;
		}
	} 
	a[1][2]=1;//给第 2 行第 3 列的那个位置赋值为 1 
	//行和列都是从 0 开始的 
	a[2][1]=2;
	a[2][3]=3;
	//输出二维数组
	for(i=0;i<4;i++){
		for(j=0;j<6;j++){
			printf("%d",a[i][j]);
		}
		printf("\n");
	} 
}

在这里插入图片描述
使用方式2:直接初始化

1)定义类型数组名 [大小] [大小]={{1,2..},{1,2..},{1,2..};2)或者类型数组名 [大小] [大小]={1,2,3,4,5,6 ..};

int[4][6]={
{0,0,0,0,0,0}
{0,0,1,0,0,0}
{0,2,0,3,0,0}
{0,0,0,0,0,0}
};

int[4][6]={0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,3,0,0,0,0,0,0,0,0}//自动匹配到各行各列

案例2:请使用灵活的方式遍历如下数组

int map[3][3]={{0,0,1},{1,1,1},{1,1,3}};
#include<stdio.h>
void main(){
	int map[3][3]={{0,0,1},{1,1,1},{1,1,3}};
	printf("%d\n",sizeof(map));//得到 map 数组的大小 4*9
	printf("%d\n",sizeof(map[0]));// 得到 map 数组第1行有多大 3*4
	int rows = sizeof(map)/sizeof(map[0]);// 得到多少行 3
	printf("%d\n",rows);
	int clos =  sizeof(map[0])/sizeof(int);//得到列  3
	printf("%d\n",clos);
}

在这里插入图片描述

案例3:遍历该二维数组,并得到和

int arr[3][2]={{4,6},{1,4},{-2,8}};//遍历该二维数组,并得到和
#include<stdio.h>
void main(){
	int i,j;
	int sum=0;
	int arr[3][2]={{4,6},{1,4},{-2,8}};
	for(i=0;i<=2;i++){
		for(j=0;j<=1;j++){
			printf("%d ",arr[i][j]);//取出每一个数 
			sum += arr[i][j];//相加 
		}
		printf("\n");
	} 
	printf("sum = %d",sum);
}

例题

1.比如我们开发一个五子棋游戏,棋盘就是需要二维数组来表示。

0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0

#include<stdio.h>
void main(){
	int a[6][6];
	int i,j;
	for(i=0;i<6;i++){
		for(j=0;j<6;j++){
			if((i+1)%2 != 0 && (j+1)%2 != 0){
				printf("%d ",a[i][j]=0);
			}
			else if((i+1)%2 == 0 && (j+1)%2 == 0){
				printf("%d ",a[i][j]=0);
			}
			else{
				printf("%d ",a[i][j]=1);
			}
		}
		printf("\n");
	} 
}

在这里插入图片描述

2.定义二维数组,用于保存三个班,每个班五名同学成绩,并求出每个班级平均分、以及所有班级平均分。


#include<stdio.h>
void main(){
	double scores[3][5];
	int i,j;
	double TScores = 0.0;  //所有班总成绩 
	double CTScores = 0.0; //各班总成绩 
	for(i=0;i<3;i++){
		for(j=0;j<5;j++){
			scores[0][0]=0.0;
		}
	} 
	for(i=0;i<3;i++){
		for(j=0;j<5;j++){
			printf("请输入第 %d 个班的第 %d 个学生成绩:",i+1,j+1);
			scanf("%lf",&scores[i][j]);
		}
	} 
	
	//统计各班总成绩 和 所有学生总成绩 
	for(i=0;i<3;i++){
		double CTScores = 0.0;//每一个班后都清零 
		for(j=0;j<5;j++){
			CTScores += scores[i][j];//累加每个班的总成绩 
		}
		printf("\n 第 %d 个班的平均成绩是:%.2f",i+1,CTScores/3); 
		TScores += CTScores;//每一个班总成绩累加得到所有学生总成绩 
	} 
	printf("\n 所有学生总成绩:%.2f 平均成绩:%.2f",TScores,TScores/15);
}

在这里插入图片描述

二维数组使用细节和注意事项

(1)可以只对部分元素赋值,未赋值的元素自动取“零”值。

#include<stdio.h>

void main(){
	int a[4][5]={{1},{2},{3},{4}};
	int i,j;
	for(i=0;i<4;i++){
		for(j=0;j<5;j++){
			printf("%d",a[i][j]);
		}
		printf("\n");
	}
}

在这里插入图片描述
(2)如果对全部元素赋值,那么第一维的长度可以不给出。

int a[3][3]={1,2,3,4,5,6,7,8,9};
也可以写成
int a[][3]={1,2,3,4,5,6,7,8,9};

(3)==二维数组可以看作是由一维数组嵌套而成的:==如果一个数组的每个元素又是一个数组,那么它就是二维数组。

二维数组a[3][4]可看成三个一维数组,它们的数组名分别为a[0]、a[1]、a[2]。
这三个一维数组都有4个元素,如:一维数组a[0]的元素为 a[0][0]、a[0][1]、a[0][2]、a[0][3]

综合体:创建一个 4*4 的数组,提示从键盘依次输入数组的各元素,之后求该数组所有元素之和、对角线元素之和,以及最大元素。(提示:可以使用两层 for 循环嵌套实现)

#include<stdio.h>

void main(){
	int i,j;
	int sum=0;
	int sum1=0;
	int max=0;
	int temp=0;
	int arr[4][4];//定义数组 
	for(i=0;i<4;i++){//循环输入
	    for(j=0;j<4;j++){
	    	printf("请输入第 %d 行的第 %d 列:",i+1,j+1);
			scanf("%d",&arr[i][j]); 
		}
    }
	
	//遍历读取每一个数 
	for(i=0;i<4;i++){
		for(j=0;j<4;j++){
			printf("%d ",arr[i][j]);//取出每一个数 
			sum += arr[i][j];//相加 
			//对角线和 
			if(i==j || i==3-j){
				sum1 += arr[i][j];
			}
			    //找最大数 
            if(arr[i][j] > max){
                max = arr[i][j];
            }	
		}
		printf("\n");
	} 
	printf("sum = %d\nsum1= %d\nmax=%d",sum,sum1,max);  
}

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值