一维数组核心知识点全解析 7/21

一维数组是编程语言中最基础的数据结构之一,用于存储相同类型的元素并按顺序排列。以下是关于一维数组的核心知识点总结:

一、基本概念

  • 定义:由相同数据类型的元素组成的线性集合,元素在内存中连续存储,通过下标(索引) 访问。
  • 特点
    • 元素类型统一(如全部为整数、字符串等)。
    • 长度固定(大部分语言中,数组创建后长度不可修改)。
    • 访问效率高(通过下标直接定位,时间复杂度为O(1))。

一维数组知识点梳理

  1. 定义:格式为 类型说明符 数组名[常量表达式]。例如 int a[10];,这里 int 是类型说明符,表示数组元素为整型;a 是数组名;[10] 中的 10 是常量表达式,表明数组 a10 个元素。常量表达式的值必须是大于 0 的整数,不能是变量,像 int n = 10; int a[n]; 这种在C语言标准中是错误的定义方式(不过有些编译器对这种可变长度数组有扩展支持 ,但标准C语言不允许)。
  2. 数组元素引用:数组元素通过数组名和下标来引用,下标从 0 开始。例如对于 int a[10];,可以通过 a[0]a[1] 一直到 a[9] 来访问各个元素,如 a[0] = 1; a[1] = 2; 等对元素进行赋值操作。
  3. 数组特性
    • 单一性:数组中每个元素所占内存空间大小相同。比如 int 型数组,每个元素通常占4个字节(不同系统和编译器可能有差异,但同一数组内元素所占字节数一致)。
    • 连续性:数组在内存中是连续存储的。这使得可以通过指针方便地对数组元素进行操作。而且数组不能整体赋值,不能像 a = b; 这样把一个数组的值直接赋给另一个数组(如果要实现类似功能,需要逐个元素赋值)。
    • 有序性:数组元素有固定的顺序,通过下标来确定位置 。数组名代表数组首元素的地址,例如 int a[10];a&a[0] 是等价的,都表示数组 a 首元素 a[0] 的地址。

二、核心要素

  1. 数据类型
    数组中所有元素的类型,决定了数组的用途。例如:

    • 整数数组(int[]):存储整数。
    • 字符串数组(String[]):存储文本。
    • 对象数组(Object[]):存储自定义对象。
  2. 长度(Length)
    数组中元素的个数,通常在创建时指定。例如:int[] arr = new int[5] 表示长度为5的整数数组。

  3. 下标(索引)

    • 用于定位元素的编号,从0开始(大部分语言),最大下标为「长度-1」。
    • 示例:长度为5的数组,下标范围是0~4。
    • 若访问超出范围的下标,会触发数组越界异常(如Java中的ArrayIndexOutOfBoundsException)。

三、声明与初始化

  1. 声明方式

    • 数据类型 数组名[];(C语言风格)
      例:String names[];

四、常用操作

  1. 访问元素
    通过「数组名[下标]」读写元素。
    例:int first = scores[0];(读);scores[1] = 90;(写)。

  2. 遍历数组
    遍历即依次访问所有元素,常用方法:

    • for循环(适合需要下标时):
      for (int i = 0; i < arr.length; i++) {
          System.out.println(arr[i]);
      }
      
    • 增强for循环(foreach)(仅需元素值时):
      for (int num : arr) {
          System.out.println(num);
      }
      
  3. 常见场景

    • 求最大值/最小值:遍历数组比较元素。
    • 求和/平均值:累加元素后计算。
    • 查找元素:遍历数组匹配目标值(线性查找)。
    • 排序:使用内置方法(如Java的Arrays.sort())或排序算法(冒泡、选择等)。

假设题目及解答(若理解有误请纠正)

假设题目是判断以下关于一维数组定义和使用的表述是否正确:

  • int n = 10; int a[n];” 表述错误,C语言标准中数组定义的长度不能是变量。
  • int a[10]; a[0] = 1; a[1] = 2;... a[9] = 9;” 表述正确,正确定义了一个有10个整型元素的数组,并对各元素进行赋值(这里用 ... 省略部分类似赋值语句)。

如果以上不是你想要的内容,请你清晰准确地描述题目需求,以便进行解答。

课上练习:

int main(void)
{
	int i,max,max1,len;
	int a[]={1,2,3,4,5,6,7,8,9,10};
	len=sizeof(a)/sizeof(a[0]);
	max=a[0];
	max1=a[0];
	for(i=1;i<len;++i)
	{
		if(max<a[i])
		{
			max=a[i];
		}
	
	}
	for(i=1;i<len;++i)
	{
		if(max1<a[i]&&a[i]!=max)

		{
			max1=a[i];
			
			

		}
	}
	printf("%d\n",max);
	printf("%d\n",max1);
	return 0;
}

这段 C 语言代码的核心思想是在给定的一维整型数组中,找出最大值和第二大值,以下是分步骤总结:

1. 初始化与准备

  • 定义变量 i 用于循环遍历,max 存储最大值、max1 存储第二大值,len 存储数组有效长度。
  • 通过 sizeof(a)/sizeof(a[0]) 计算数组元素个数(利用数组总字节数除以单个元素字节数),让代码适配数组长度变化。

2. 找最大值(第一遍循环)

遍历数组(从第 2 个元素 i=1 开始),逐个比较元素与 max

  • 若当前元素 a[i] 大于 max,更新 maxa[i]
  • 遍历结束后,max 即为数组的最大值

3. 找第二大值(第二遍循环)

再次遍历数组(同样从 i=1 开始),筛选满足两个条件的元素:

  • 元素值大于 max1(初步筛选较大值 )。
  • 元素值不等于 max(排除最大值,确保找“第二大” )。
  • 遍历结束后,max1 即为数组的第二大值

4. 输出结果

最后通过 printf 分别打印最大值 max 和第二大值 max1,完成逻辑闭环。

简言之,代码通过两次遍历数组,第一次锁定最大值,第二次在排除最大值的前提下找次大值,实现了从数组中提取 “最大 + 第二大” 两个关键数据的需求 。

数组的逆序:

int main(void)   //逆序
{
	int i,len;
	int a[]={1,2,3,4,5,6,7};
	len=sizeof(a)/sizeof(a[0]);
	for(i=0;i<len/2;++i)
	{
		int t;
		t = a[i];
		a[i] = a[len - i - 1];
		a[len-i-1]= t ; 
	}
	for(i=0;i<len;++i)
	{
		printf("%d\n",a[i]);
	}
	return 0;
}

这段代码的核心思想是通过对称位置元素互换的方式,实现数组元素的原地逆序排列,具体逻辑如下:

1. 核心目标

将数组中元素的顺序反转(例如原数组 [1,2,3,4,5,6,7] 变为 [7,6,5,4,3,2,1]),且不依赖额外数组存储,直接在原数组上操作。

2. 关键实现逻辑

  • 计算数组长度:通过 sizeof(a)/sizeof(a[0]) 得到数组元素个数 len,确保代码适配不同长度的数组。
  • 对称位置互换:仅需遍历数组前半部分(i0len/2 - 1),每次将第 i 个元素与对称位置的第 len-i-1 个元素互换:
    • 例如当 i=0 时,交换第 0 个元素和第 6 个元素(7-0-1=6
    • i=1 时,交换第 1 个元素和第 5 个元素,以此类推
  • 遍历终止条件:循环到 i < len/2 时停止,避免对已交换的元素重复操作(例如长度为7的数组,只需交换3次即可完成全部逆序)。

3. 最终效果

通过上述对称互换操作,数组元素实现了完全逆序,最后通过循环打印出逆序后的所有元素。

这种方法的优势是空间效率高(仅用一个临时变量 t 辅助交换),且时间效率优(只需遍历数组一半元素)。

选择排序

int main(void)
{
	int i,len;
	int a[]={3,7,5,6,2,8,5,4};
	len=sizeof(a)/sizeof(a[0]);
	for(i=0;i<len-1;++i)
	{
		int j;
		for(j=i+1;j<len;++j)
		{
			if(a[i]>a[j])
			{
				int t;
				t=a[i];

				a[i]=a[j];
				a[j]=t;
			}
		}
	}
	for(i=0;i<len;++i)
	{
		printf("%d\n",a[i]);
	}


	return 0;
}

这段代码的核心思想是使用选择排序算法对数组进行升序排序,具体逻辑如下:

1. 核心目标

将数组元素按照从小到大的顺序重新排列(例如原数组 [3,7,5,6,2,8,5,4] 排序后变为 [2,3,4,5,5,6,7,8])。

2. 关键实现逻辑(选择排序)

  • 外层循环控制排序轮次i0len-2 循环(共 len-1 轮),每轮确定数组第 i 个位置的元素。
  • 内层循环寻找最小值ji+1len-1 循环,在 i 位置之后的元素中寻找比 a[i] 更小的值:
    • 若找到 a[j] < a[i],则交换 a[i]a[j],确保每轮结束后,a[i] 是剩余未排序元素中的最小值。
    • 例如第一轮 i=0 时,会找到整个数组的最小值放到 a[0] 位置;第二轮 i=1 时,会找到剩余元素的最小值放到 a[1] 位置,以此类推。

3. 最终效果

经过 len-1 轮排序后,整个数组完成升序排列,最后通过循环打印出排序后的所有元素。

这种排序方法的特点是每轮只进行一次元素交换(找到最小值后才交换),逻辑直观,适合理解排序算法的基本思想。

冒泡排序:

int main(void) //冒泡排序
{
	int j,i;
	int a[]={2,5,7,8,6,23,10};
	int len;
	len=sizeof(a)/sizeof(a[0]);
	for(j=len-1;j>0;--j)
	{
		
		for(i=0;i<j;++i)
		{
			if(a[i]>a[i+1])
			{
				int t;
				t=a[i];
				a[i]=a[i+1];
				a[i+1]=t;
			}
		}
	}
	for(i=0;i<len;++i)
	{
		printf("%d\n",a[i]);
	}
	return 0;
}

这段代码的核心思想是使用冒泡排序算法对数组进行升序排序,其核心逻辑如下:

1. 核心目标

将数组元素按照从小到大的顺序排列(例如原数组 [2,5,7,8,6,23,10] 排序后变为 [2,5,6,7,8,10,23])。

2. 关键实现逻辑(冒泡排序)

  • 外层循环控制排序范围j 从数组末尾(len-1)向头部(1)递减,每轮循环后,最大的元素会"浮"到当前未排序部分的末尾,因此下一轮无需再处理已排好的尾部元素。
  • 内层循环执行相邻比较与交换i 从数组头部(0)遍历到 j-1,每次比较相邻的两个元素 a[i]a[i+1]
    • a[i] > a[i+1](即前一个元素大于后一个元素),则交换两者位置,确保较大的元素向后移动。
    • 例如第一轮 j=6 时,会通过多次相邻交换,将最大元素 23 移到数组最后;第二轮 j=5 时,将第二大元素 10 移到倒数第二位,以此类推。

3. 最终效果

经过 len-1 轮排序后,数组完成升序排列,最后通过循环打印出排序结果。

这种排序方法的特点是通过相邻元素的多次比较和交换,让较大的元素像"气泡"一样逐步上浮到正确位置,逻辑简单易懂,是经典的基础排序算法。

插入排序

int main(void)
{
	int a[]={2,3,6,9,5,1,3,7};
	int len=sizeof(a)/sizeof(a[0]);
	int b[len],i;
	b[0]=a[0];
	for(i=1;i<len;++i)
	{
		int t=a[i];
		int j=i;
		while(j>0&&b[j-1]>t)
		{
			b[j]=b[j-1];
			--j;
		}
		b[j]=t;
	}
	for(i=0;i<len;++i)
	{
		a[i]=b[i];
	}
	for(i=0;i<len;++i)
	{
		printf("%d\n",b[i]);
	}
	return 0;
}

这段代码的核心思想是使用插入排序算法对数组进行升序排序,具体逻辑如下:

1. 核心目标

将原数组 a 中的元素按照从小到大的顺序重新排列(例如原数组 [2,3,6,9,5,1,3,7] 排序后变为 [1,2,3,3,5,6,7,9])。

2. 关键实现逻辑(插入排序)

  • 借助辅助数组:创建与原数组长度相同的辅助数组 b,用于逐步构建有序序列。
  • 初始化有序序列:先将原数组的第一个元素 a[0] 放入 b[0],作为有序序列的起始元素。
  • 逐个插入元素:从原数组的第二个元素(i=1)开始,依次将每个元素 a[i] 插入到辅助数组 b 的合适位置:
    • 暂存当前要插入的元素 t = a[i]
    • b 中已排序部分的末尾(j=i)向前比较,找到第一个不大于 t 的元素位置。
    • 在比较过程中,若 b[j-1] > t,则将 b[j-1] 向后移动一位(为 t 腾出位置)。
    • 找到合适位置后,将 t 插入到 b[j] 处。
  • 同步结果到原数组:排序完成后,将辅助数组 b 中的有序元素复制回原数组 a

3. 最终效果

通过将每个元素逐一插入到已排序序列的正确位置,最终形成完整的有序数组,最后打印排序结果。

这种排序方法的特点是模拟了手工整理扑克牌的过程,将新元素插入到已排序序列的合适位置,对于部分有序的数组效率较高。

作业题:

1、已知数组a[10]和b[10]中元素的值递增有序,将两个数组合并为一个数组(有序)并完成打印;

int main(void)
{
	int a[]={1,3,5,7,9,11,13,15,17,19};
	int b[]={2,4,6,8,10,12,14,16,18,20};
	int len1=sizeof(a)/sizeof(a[0]);
	int len2=sizeof(b)/sizeof(b[0]);
	int c[len1+len2];
	int i,x;
	for(i=0;i<len1;++i)
	{
		c[i]=a[i];
	}
	for(i=len1,x=0;i<len1+len2,x<len2;++i,++x)
	{
		c[i]=b[x];
	}
//	for(i=0;i<len1+len2;++i)
//	{
//		printf("%d\n",c[i]);
//	}
	int j; 
	for(j=len1+len2-1;j>0;--j)
	{
		for(i=0;i<j;++i)
		{
			if(c[i]>c[i+1])
			{
				int t;
				t=c[i];
				c[i]=c[i+1];
				c[i+1]=t;
			}
		}
	}
	for(i=0;i<len1+len2;++i)
	{
		printf("%d\n",c[i]);
	}




	return 0;
}

这段代码的核心解题步骤是合并两个有序数组并对合并后的数组进行排序,具体可分为以下三个关键步骤:

1. 准备工作:定义数组并计算长度

  • 定义两个有序数组 a(奇数序列)和 b(偶数序列),以及一个用于存储合并结果的数组 c
  • 计算数组 a 的长度 len1 和数组 b 的长度 len2,确定合并后数组 c 的长度为 len1 + len2

2. 合并数组:将两个数组合并到新数组

  • 第一步合并:将数组 a 的所有元素依次放入数组 c 的前半部分(c[0]c[len1-1])。
  • 第二步合并:将数组 b 的所有元素依次放入数组 c 的后半部分(c[len1]c[len1+len2-1])。
    此时数组 c 中元素为 [1,3,5,...,19,2,4,6,...,20](尚未排序)。

3. 排序合并后的数组:使用冒泡排序实现升序

  • 对合并后的数组 c 执行冒泡排序:
    • 外层循环 j 从数组末尾向头部递减,控制每轮排序的范围(每轮确定一个最大值的位置)。
    • 内层循环 i 从数组头部遍历到 j-1,通过相邻元素比较和交换,将较大的元素逐步"浮"到当前范围的末尾。
  • 排序完成后,数组 c 变为完全升序的序列 [1,2,3,4,...,19,20]

4. 输出结果

通过循环打印排序后的数组 c 的所有元素,完成整个流程。

简言之,这段代码的核心逻辑是先合并、后排序,通过简单的数组拷贝完成合并,再用冒泡排序对合并结果进行整理,最终得到一个有序的完整数组。

2、从终端输入一个n将数组int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}

完成如下变化,并打印,操作方式如下:

n:2 8 9 1 2 3 4 5 6 7
n:3 7 8 9 1 2 3 4 5 6

int main(void)
{
	int a[]={1,2,3,4,5,6,7,8,9};
	int len=sizeof(a)/sizeof(a[0]);
	int t,i;
	scanf("%d",&t);
	int s;
	for(s=0;s<t;++s)
	{
		int j;
		j=len-1;
		int u=a[j];
		while(j>0)
		{
			a[j]=a[j-1];
			--j;
		}
		a[j]=u;
	}
	for(i=0;i<len;++i)
	{
		printf("%d",a[i]);
	}

	return 0;
}

这段代码的核心逻辑是将数组元素进行指定次数的右循环移位,具体实现步骤如下:

1. 核心目标

接收用户输入的移位次数 t,将数组 a 中的元素向右循环移动 t 次(例如原数组 [1,2,3,4,5,6,7,8,9],若 t=1 则变为 [9,1,2,3,4,5,6,7,8])。

2. 关键实现逻辑

  • 初始化与输入:定义数组 a 并计算其长度 len,通过 scanf 获取用户输入的移位次数 t
  • 循环执行右移操作
    • 外层循环控制移位总次数(共执行 t 次)。
    • 每次右移的具体操作(内层逻辑):
      1. 暂存数组最后一个元素 u = a[len-1](即将被移到首位的元素)。
      2. 通过 while 循环将数组中从倒数第二个元素到第一个元素依次向后移动一位(a[j] = a[j-1])。
      3. 将暂存的最后一个元素 u 放到数组的第一个位置 a[0],完成一次右移。
  • 输出结果:移位完成后,遍历数组并打印所有元素。

3. 特点说明

这种右循环移位的方式,每次只移动一个元素到首位,通过 t 次重复操作实现整体移位效果,逻辑直观但效率较低(时间复杂度为 O(t×n),其中 n 为数组长度)。例如当 t=2 时,原数组 [1,2,3,4,5,6,7,8,9] 会先变为 [9,1,2,3,4,5,6,7,8],再变为 [8,9,1,2,3,4,5,6,7]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值