一维数组是编程语言中最基础的数据结构之一,用于存储相同类型的元素并按顺序排列。以下是关于一维数组的核心知识点总结:
一、基本概念
- 定义:由相同数据类型的元素组成的线性集合,元素在内存中连续存储,通过下标(索引) 访问。
- 特点:
- 元素类型统一(如全部为整数、字符串等)。
- 长度固定(大部分语言中,数组创建后长度不可修改)。
- 访问效率高(通过下标直接定位,时间复杂度为O(1))。
一维数组知识点梳理
- 定义:格式为
类型说明符 数组名[常量表达式]。例如int a[10];,这里int是类型说明符,表示数组元素为整型;a是数组名;[10]中的10是常量表达式,表明数组a有10个元素。常量表达式的值必须是大于0的整数,不能是变量,像int n = 10; int a[n];这种在C语言标准中是错误的定义方式(不过有些编译器对这种可变长度数组有扩展支持 ,但标准C语言不允许)。 - 数组元素引用:数组元素通过数组名和下标来引用,下标从
0开始。例如对于int a[10];,可以通过a[0]、a[1]一直到a[9]来访问各个元素,如a[0] = 1; a[1] = 2;等对元素进行赋值操作。 - 数组特性:
- 单一性:数组中每个元素所占内存空间大小相同。比如
int型数组,每个元素通常占4个字节(不同系统和编译器可能有差异,但同一数组内元素所占字节数一致)。 - 连续性:数组在内存中是连续存储的。这使得可以通过指针方便地对数组元素进行操作。而且数组不能整体赋值,不能像
a = b;这样把一个数组的值直接赋给另一个数组(如果要实现类似功能,需要逐个元素赋值)。 - 有序性:数组元素有固定的顺序,通过下标来确定位置 。数组名代表数组首元素的地址,例如
int a[10];,a和&a[0]是等价的,都表示数组a首元素a[0]的地址。
- 单一性:数组中每个元素所占内存空间大小相同。比如
二、核心要素
-
数据类型
数组中所有元素的类型,决定了数组的用途。例如:- 整数数组(
int[]):存储整数。 - 字符串数组(
String[]):存储文本。 - 对象数组(
Object[]):存储自定义对象。
- 整数数组(
-
长度(Length)
数组中元素的个数,通常在创建时指定。例如:int[] arr = new int[5]表示长度为5的整数数组。 -
下标(索引)
- 用于定位元素的编号,从0开始(大部分语言),最大下标为「长度-1」。
- 示例:长度为5的数组,下标范围是0~4。
- 若访问超出范围的下标,会触发数组越界异常(如Java中的
ArrayIndexOutOfBoundsException)。
三、声明与初始化
-
声明方式
数据类型 数组名[];(C语言风格)
例:String names[];
四、常用操作
-
访问元素
通过「数组名[下标]」读写元素。
例:int first = scores[0];(读);scores[1] = 90;(写)。 -
遍历数组
遍历即依次访问所有元素,常用方法:- for循环(适合需要下标时):
for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } - 增强for循环(foreach)(仅需元素值时):
for (int num : arr) { System.out.println(num); }
- for循环(适合需要下标时):
-
常见场景
- 求最大值/最小值:遍历数组比较元素。
- 求和/平均值:累加元素后计算。
- 查找元素:遍历数组匹配目标值(线性查找)。
- 排序:使用内置方法(如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,更新max为a[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,确保代码适配不同长度的数组。 - 对称位置互换:仅需遍历数组前半部分(
i从0到len/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. 关键实现逻辑(选择排序)
- 外层循环控制排序轮次:
i从0到len-2循环(共len-1轮),每轮确定数组第i个位置的元素。 - 内层循环寻找最小值:
j从i+1到len-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次)。 - 每次右移的具体操作(内层逻辑):
- 暂存数组最后一个元素
u = a[len-1](即将被移到首位的元素)。 - 通过
while循环将数组中从倒数第二个元素到第一个元素依次向后移动一位(a[j] = a[j-1])。 - 将暂存的最后一个元素
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]。

1425

被折叠的 条评论
为什么被折叠?



