什么是数组:
- 数组用来将相同数据类型存储在存储单元里组成的构造类型;
- 数组的每个成员称为一个数组元素
一、一维数组
(一) 一维数组定义
数据类型 [ ] 数组名;
ex: int [ ] age; float [ ] scores; string [ ] names;
(二) 一维数组初始化
在定义数组后,必须对其进行初始化才能够使用
1) 动态初始化
数据类型 [ ] 数组名 = new 数据类型 [ 数组长度 ];
//例如:
int [ ] intArray = new int [6]; //【数组元素为默认值】
数据类型 [ ] 数组名 = new 数据类型 [ 数组长度 ] { 元素1, 元素2 };
栈内存 堆内存
//例如:
int [ ] intArray = new int [3]{1,2,3};
//或者:
int [ ] intArray = new int []{1,2,3};
2) 静态初始化
数据类型 [ ] 数组名 = { 元素1, 元素2, ...... 元素n };
//例如:
int[] intArray = {1,2,3};
注:在这种情况下,不能将数组定义和静态初始化分开
(三) 数组元素
1) 数组下标
数组元素在数组中的序号
- 数组下标从0开始计数
- 数组下标可以是常量也可以是变量
- 数组长度:arr.Length表示数组的长度,是只读的
2) 数组元素的访问
- 元素访问: 数组名[ 下标 ]
ex: intArray[3];
- 访问数组时,切记下标所对应的数组元素是存在的,如果不存在,就会引发数组越界异常。
(四) 数组赋值
数组属于一种引用类型,因此如果将数组名 b 赋给数组 a,那么数组 b 在操作数组元素时,实质上操作的还是数组 a。
值类型与引用类型:
(五) 遍历数组
访问数组中的每一个元素
int[] array = {19,81,05,06,19,82,12,20};
for(int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);
}
注意:
- 系统不会检测数组元素的下标是否越界,编程时,必须保证数组下标不能越界
- 数组是一个整体,不能直接参加运算(= 除外),只能对单个数组元素进行处理,通常用到数组的地方都会用到循环
- 数组定义好后,长度不能变更,除非重新分配内存
二、冒泡排序
1)思想:
- 当前数组元素与后面的数组元素进行对比,如果前大后小,则进行交换
- 每轮可以确定一个最大值在数组末尾,几轮之后即可完成排序
- 冒泡排序当然也可以从大到小排序,那样则前小后大进行交换
2) 代码:
int[] array = {5,6,2,12,1,20};
//外层循环,需要交换几轮
for(int i = 0; i < array.Length - 1; i++)
{
//内层循环,某轮交换中需要交换几次
for(int j = 0; j < array.Length - i - 1; j++)
{
if(array[j] > array[j + 1])
{
int num = array[j];
array[j] = array[j + 1];
array[j + 1] = array[j];
}
}
}
//排序完成,遍历数组,按照排好的顺序输出数组元素
for(int i = 0; i < array.Length; i++)
{
Console.Write(array[i]+"\t");
}
3) 优化:
如果循环没有结束,排序已经完成了,继续循环和对比岂不是无用功?
int[] array = {5,6,2,12,1,20};
for(int i = 0; i < array.Length; i++)
{
//立一个flag,表示判断过程中是否发生了交换
bool isExchange = false; //初值为没有交换
for(int j = 0; j < array.Length - i -1; i++)
{
if(array[j] > array[j + 1])
{
//进入了if语句,说明进行了交换
isExchange = true;
int num = array[j];
array[j] = array[j + 1];
array[j + 1] = num;
}
}
if(!isExchangr) //!isExchange:没有交换
{
//说明已经排好序了,就没有必要再进行后面的交换了
break;
}
}
//排序结束,进行输出工作
Console.WriteLine("排序结束");
for(int i = 0; i < array.Length; i++)
{
Console.Write(array[i] + "\t");
}