C语言:数组入门及其基础算法详解

C语言:数组入门及其基础算法详解(๑•̀ㅂ•́)و✧

本篇文章我会用我的理解介绍什么是数组,以及数组的一些基础算法,包含顺序查找,寻找最大值/最小值,数据插入,数据删除,数据倒置,冒泡排序,选择排序,二分查找共八个算法讲解及示例。

一.什么是数组?

本篇文章的重点是算法详解,基本概念简单提一下。

定义

你可以把数组想象成一个有很多个格子的储物柜,其有以下特性:

  • 同一数据类型: 储物柜每个格子都只能存放同种类型 的物品(比如全是书或者全是衣服),在编程中,即元素均为同种数据类型(全是整型int或全是字符型char)
  • 连续内存空间: 这些格子是一个接一个,连续排列的
  • 下标(索引)访问: 每个格子都有一个编号,我们称作下标或索引,且编号从0开始

表示

基本格式:

  • 数组数据类型 数组名称[元素个数];
  • 数组数据类型 数组名称[(元素个数)]={元素1,元素2...元素n};

第二种形式下的元素个数可不写,系统会自动计算后面{}中的元素个数,若填写,此形式下的"元素个数"应≥n

eg:int num[5] ={1,2,3,4,5}; 其中,num[0] = 1;num[3] = 4;

常用基础算法(。•̀ᴗ-)✧

以下算法全部基于 int num[5] = {1,2,3,4,5};进行

1.顺序查找

就像在一排房子里找人,从第一家开始问

eg : 查找数组 num 中值为 4 的元素及其位置

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {1,2,3,4,5};
    int n = 4;//要找的元素
    int found = 0;//0表示没找到,1表示找到了,先假设没找到
    
    int i;
    //从第一个开始逐个寻找(也称遍历数组)
    for(i = 0;i < 5;i++){
    	if(num[i]==n){ //如果第i位数字等于n,代表找到
    		found = 1;
    		break;//找到就停止循环
		}
	}
	if(found==1){
		printf("找到了!%d在数组第%d位",n,i+1); //注意:数组从0开始计数,因此此处为i+1
	}
	else{
		printf("没找到!");
	}
    return 0;
}

//输出
//找到了!4在数组第4位

2.寻找最大值/最小值

就像选班长,先定下一个人,再跟其他人进行比较

eg : 寻找并输出数组 num 中的最大值

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {1,2,3,4,5};
    int n = 4;
    int max = num[0];//先假设最大值为num[0],即1
    
    int i;
    //遍历数组
    for(i = 1;i < 5;i++){//此处i从1开始,因为num[0]已经被假设为最大值,不需要再和自己比较一次
    	if(num[i]>max){
    		max = num[i];//找到更大的就更新
		}
	}
printf("最大值为%d",max);
    return 0;
}

//输出
//最大值为5

3.数据插入

就像排队插队,后面的人都要往后挪一位

eg :先输出插入前的数组 num ,再在数组 num 中第2位和第3位数字中间插入一个数字10并输出插入后的新数组

c 复制代码
#include <stdio.h>

int main() {
    int num[6] = {1,2,3,4,5};
    int n = 10;//要插入的数字
    int position = 2;//要插入的位置(第3位)(数组从0开始计数,因此此处是2)
    
    //打印插入前数组
    for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
	printf("\n");
   
   //开始插入操作
   //从后往前,将插入位置及其之后的元素往后移一位
	for(int i = 4;i>=position;i--){
        //思考此处i为什么不能等于5?因为此时数组计数范围为0~5共6个数字,若i=5,在执行下行操作时,会变成num[6]=num[5],num[6]超过计数范围(也称越界),程序错误
		num[i+1] = num[i];
	}
        
   //插入新值n
	num[position] = n;
        
   //打印插入后的新数组
	for(int i = 0;i < 6;i++){
    	printf("%d ",num[i]);
	}
    return 0;
}

//输出
//1 2 3 4 5
//1 2 10 3 4 5

4.数据删除

就像有人离开队伍,后面的人往前补上

eg : 先输删除前的数组,再将数组中值为3的元素删除并输出删除后的新数组

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {1,2,3,4,5};
    int position = 2;//要删除的位置(第三位)
    
    //打印删除前的数组
    for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
	printf("\n");

    //开始删除操作
    //从前往后,将删除位置之后的位置往前进一位
	for(int i = position+1;i<5;i++){//注意这里删除位置不参与循环,所以i=position+1
		num[i-1] = num[i];
	}
	
    //打印删除后的数组
	for(int i = 0;i < 4;i++){
    	printf("%d ",num[i]);
	}
    return 0;
}

//输出
//1 2 3 4 5 
//1 2 4 5 

5.数据倒置

就像把一本书倒过来读

eg : 先将原数组打印,再将数组 num 按相反顺序打印

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {1,2,3,4,5};
    
    //打印原数组
    for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
	printf("\n");
  
   //开始倒置操作
   //交换第一个和最后一个,交换第二个和倒数第二个
	for(int i = 0;i<2;i++){//只需要执行 交换前一半 的操作,因此i<2
		int temp = num[i];
		num[i] = num[4-i];
		num[4-i] = temp;
	}
   
   //打印倒置后的数组
	for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
    return 0;
}

//输出
//1 2 3 4 5
//5 4 3 2 1

如果觉得这种方法不好理解,也可以使用另一种(也是我比较喜欢用的一种):定义一个新的空数组,将数组 num 从后往前遍历,并依次从前往后填入新数组,新数组即为倒置后的数组num.(可以尝试一下,这里就不写出来了,我觉得很好理解(~ ̄▽ ̄)~

6.冒泡排序(每轮排出最大的数)

就像水中的气泡,大的往上冒(虽然这么取名,但从小到大排列和从大到小排列均可用此方法)

这个算法我认为直接看代码和注释很抽象,很难理解,建议先上网搜索"冒泡排序算法动画演示"先看视频理解一下,我觉得帮助很大(=`ω´=)

eg : 先将数组 int num[5] = {2,5,4,1,3}; 打印,再将其内元素按从小到大的顺序输出

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {2,5,4,1,3};
    
    //打印原数组
    for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
	printf("\n");
	
    //开始冒泡排序
	for(int i = 0;i<4;i++){ //需要比较4轮,即(数组元素个数-1)轮
		for(int j = 0;j<4-i;j++){ //每轮比较次数减小
			if(num[j]>num[j+1]){ //如果前面的比后面的大
                        //交换两个数
				int temp = num[j+1];
				num[j+1] = num[j];
				num[j] = temp;
			}
		}
	}

    //打印排序后的数组
	for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
    return 0;
}

//输出
//2 5 4 1 3
//1 2 3 4 5

7.简单选择排序(每轮排出最小的数)

就像选最小的苹果放到最前面(同6.此方法可用于从小到大和从大到小排序)

和冒泡排序一样,建议配合网上的执行动画一起看( ˙꒳˙ )

eg : 先将数组 int num[5] = {2,5,4,1,3}; 打印,再将其内元素按从小到大的顺序输出

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {2,5,4,1,3};
    
    //打印原数组
    for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
	printf("\n");
	
    //开始选择排序
	for(int i = 0;i<4;i++){ //需要选择4次,即(数组元素个数-1)次
		int min = i;//假设最小的数是数组第i位元素
		
                
                //在剩下的里面找真正的最小值
		for(int j = i+1;j<5;j++){
			if(num[j]<num[min]){ //依次比较,找出最小值
				min = j;
			}
		}
		
                //若假设的最小值不是真正的最小值,则将这两个元素互换位置
		if(min != i){
			int temp = num[i];
			num[i] = num[min];
			num[min] = temp;
		}
	}
       
     //打印排序后的数组
	for(int i = 0;i < 5;i++){
    	printf("%d ",num[i]);
	}
    return 0;
}

//输出
//2 5 4 1 3
//1 2 3 4 5

8.二分查找(!!!要求数组必须是有序的)

就像猜数字游戏,每次都猜中间值

eg : 查找 num 数列中值为30的元素并打印其位置

c 复制代码
#include <stdio.h>

int main() {
    int num[5] = {1,2,3,4,5};
    int n = 3; //要找的数
    
    int left = 0; //左边起点
    int right = 4; //右边起点
    int found = 0; //是否找到
    
    while(left<=right){
    	int mid = (left+right)/2; //中间位置
    	
    	printf("在%d到%d之间查找,中间是%d\n",left,right,mid);
    	
    	if(num[mid]==n){
    		printf("找到了!在第%d个位置(下标%d)\n",mid+1,mid);
    		found = 1;
    		break;//找到输出,并停止循环
		}
		else if(num[mid]<n){ //中间的数小于要找的数
			left = mid+1; //在右半边找
		}
		else{ //中间的数大于要找的数
			right = mid-1; //在左半边找
		}
	}
	
	if(!found){
		printf("没找到");
	}
    
    
    return 0;
}

//输出
//在0到4之间查找,中间是2
//找到了!在第3个位置(下标2)

以上为本篇文章全部内容,累死我了,结束\( ̄︶ ̄)/!

相关推荐
say_fall1 小时前
WinAPI 极简教程:超简单的 Windows 接口入门
c语言·windows
星轨初途3 小时前
数据结构二叉树之链式结构(3)(下)
c语言·网络·数据结构·经验分享·笔记·后端
fashion 道格3 小时前
深入理解数据结构:单链表的 C 语言实现与应用
c语言·数据结构
yuuki2332334 小时前
【C语言&数据结构】二叉树的链式递归
c语言·数据结构·后端
智者知已应修善业4 小时前
【51单片机LED贪吃蛇】2023-3-27
c语言·c++·经验分享·笔记·嵌入式硬件·51单片机
福尔摩斯张13 小时前
Axios源码深度解析:前端请求库设计精髓
c语言·开发语言·前端·数据结构·游戏·排序算法
在繁华处13 小时前
C语言经典算法:汉诺塔问题
c语言·算法
Bona Sun14 小时前
单片机手搓掌上游戏机(十一)—esp8266运行gameboy模拟器之硬件连接
c语言·c++·单片机·游戏机
酸钠鈀14 小时前
模拟IIC通讯 基于状态机
c语言