7.1数组概述
简单问题:求4个整数的最大值?求四个整数的最大值?
如何表示4个整数? –用4个整数变量
如何求出最大值? –注意比较这4个变量的大小获取值
定义4个类型变量赋值,定义int类型变量max记录初始的值。 比较第一个与第二个值的大小关系,再使用max变量记录相对较大的值。然后再跟第三个及第四个比较。最后获取到的max就是4个数中的最大值。
想一想


数组概念:数组是具有相同数据类型的一组数据的集合。数组中的每一个变量称为数组的元素,数组能够容纳元素的数量称为数组的长度。 80–数组长度

变量与数组:
变量:保存一个数据。
数组:保存多个相同类型数据。 int a= XXX; 可以存储多个不同的数据值
比一维数组多就是多维数组(主要是二维数组)。 Array类:所有数组的基类。
常见数组类型:
整形数组:数组里面存储的值都是整数类型。
小数数组:flaot或double类型,存储小数类型数据。
字符数组:存储的都是字符类型的。
字符串数组:字符串中数据元素都要用双引号引起来。
一维数组的创建及使用
书架–类似一个一维数组。
一维数组:相同类型数据的线性集合。
每个元素可以存储不同的内容,数据类型要求相同。(内容不同,类型必须相同。)
使用数组有下标或索引–从0开始依次往后排序。
开发程序:需要处理相同类型的数据或给某个方法传递相同类型数据的时候考虑使用一维数组。
车间:一维数组中的元素。可以单独取出来使用。 也可以组合在一起使用。
创建一维数组
语法:数组元素类型[ ] 数组名字; 数组名字只要符合标识符命名规则就可以。
注:下面的数组名不可以和上面的数组名相同。

实际开发环境中不可以定位两个同名的数组名称。
初始化一维数组
初始化:赋值的意思。
初始化一维数组:就是给一维数组数组赋初值。
数组初始化三种方法:
第一种:为一维数组中的每个元素进行单独赋值。
第二种:同时为整个数组进行赋值(用大括号,赋的初值中间用,隔开)。
第三种:同时为整个数组元素赋值(直接省略大括号对一维数组直接赋值)。
.NET编译器会直接根据所赋值长度自动计算出数组长度。
内存中数组存储形式:
第一种:数组中最后一个元素的索引一定比长度少1。
为数组中每个元素赋值时数据存储方式。
存储形式跟每个元素赋值的存储形式一样(都是在内存空间里申请了三个位置来存储不同的元素)。
第二种和第三种:同时为数组赋初始值的时候生成长度为3的数组
(.NET编译器根据初始值自动计算出的一个长度。)
存储形式跟每个元素赋值的存储形式一样(都是在内存空间里申请了三个位置来存储不同的元素)。
思考:声明一维数组赋初始值
int[ ] array = new int[5] { 0, 1 ,2}; // 声明并初始化一维数组 –这段代码在C++可行,另外两个值默认是0
注:C#里定义一维数组指定长度:C#赋初始值个数要与指定长度一样。
声明一维数组:首先声明一维数组初始值后面再跟【】
第三个:初始化时初始值长度也是3
第四个:前后数据类型不一致。
一维数组的使用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 一维数组的创建及使用2
{
internal class Program
{
static void Main(string[] args)
{
//使用一维数组输出每个月的天数。
int[] arr = new int[12] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//定义一维数组长度进行存储
for (int i = 0; i < 12; i++) //for循环遍历 12是数组长度 访问其中元素时候的索引比长度小
{
Console.WriteLine((i + 1) + "月有" + arr[i] + "天");//i+1表示月份 几月有多少天直接输入访问到的数组元素 直接通过索引访问数组元素
}
Console.ReadLine();//定位控制台窗体
}
}
}
多维(二维)数组的创建
二维数组声明形式:
数据类型[,] 数组名; //n个, n+1维数组
数据类型[][] 数组名; //n对中括号就是n对数组。
创建二维数组:

0,0 访问二维数组的第一行第一列元素。
0,1 访问二维数组第一行第二列数据。
实际开发中:使用二维数组存储二维表中的数据。
二维数组的行和列
为二维数组设置大小
第一种:int[,] a=new int[2,4]; 创建一个名称为a的两行四列的二维数组
new关键字分配存储空间,指定行数和列数。
第二种:
在数据类型跟两对中括号只需要指定二维数组的行数不能指定它的列数。
int[][] a = new int[2][];
a[0] = new int[2];
a[1] = new int[3];
注: //int[][] a = new int[2][3];//如果使用这种形式不能指定列数
需要先指定行再指定列,为每行指定列不同。
为二维数组设置大小的注意事项
指定列数提示错误 只能指定行数不能指定列数
//int[][] a = new int[2][3];//如果使用这种形式不能指定列数
初始化二维数组
第一种:为单个二维数组元素进行赋值。为二维数组每一行每一列元素进行赋值。
第二种:可以为每一维数组元素进行赋值。 指定行数列数不指定,对二维数组的每一行赋值。
第三种:可以同时为整个二维数组进行赋值。要求使用二维数组的第一种方式创建二维数组。
1.指定行和列一定要和指定的行和列相对应。
2.省略行和列直接进行初始化。对二维数组每一行赋值。对每一行进行初始化。
3.直接在{}里面声明,{}里面嵌套{}直接对二维数组声明。第一个指定行和列{第一行数据} 第二个省略行和列个数{}是第二行数据 同时为整个二维数组进行赋值。
以上三个整体对二维数组进行初始化
二维数组的使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 二维数组的创建与使用
{
internal class Program
{
static void Main(string[] args)
{
//int[][] a = new int[2][3];//如果使用这种形式不能指定列数
int[,] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; //定义三行三列二维数组
Console.WriteLine("—————原始数组——————");
for (int i = 0; i < 3; i++)//for循环遍历二维数组
{
for (int j = 0; j < 3; j++)
{
Console.Write(arr[i, j] + " ");//行索引与列索引用逗号隔开 每一个元素之间用空格隔开
}
Console.WriteLine();
}//输出原始数组
//调换原始数组行列位置
int temp;//定义int类型变量
for (int i = 0; i < 3; i++) //调换类型数据
{
for(int j = 0; j < i; j++)
{
temp = arr[i, j];//temp临时变量记录i和j位置的数据
arr[i, j] = arr[j, i];//数据位置调换
arr[j, i] = temp;//j和i数据换成临时变量记录的数据
}
}
Console.WriteLine("—————调换后的数组——————");
for (int i = 0; i < 3; i++)//for循环遍历二维数组
{
for (int j = 0; j < 3; j++)
{
Console.Write(arr[i, j] + " ");//行索引与列索引用逗号隔开 每一个元素之间用空格隔开
}
Console.WriteLine();
}//输出原始数组
}
}
}
不规则数组
声明二维数组的第二种方式:声明数据类型的后面跟两队中括号。只能指定行数,列数不指定。
三行不规则二维数组,每一行数组元素不同。
数组的基本操作
遍历,输入输出,排序
输出同样使用单层循环实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 用for循环实现一维数组的输入与输出
{
internal class Program
{
static void Main(string[] args)
{
int[] arr = new int[100];
for (int i = 0; i < 100; i++)
{
arr[i] = i + 1;
}
for(int i = 0;i < arr.Length; i++)//数组长度用Length属性获取
{
Console.WriteLine(arr[i]);//通过索引输出 里面是索引号
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 用while循环实现一维数组的输入与输出
{
internal class Program
{
static void Main(string[] args)
{
int[] arr = new int[100];
for (int i = 0; i < 100; i++)
{
arr[i] = i + 1;
}
//for(int i = 0;i < arr.Length; i++)//数组长度用Length属性获取
//{
// Console.WriteLine(arr[i]);//通过索引输出 里面是索引号
//}
//while循环
int index = 0;
while (index < 100)
{
Console.WriteLine(arr[index]);
index++;
}
Console.ReadLine();
}
}
}
二维数组的输入与输出
双层循环实现 100位数组用100次循环 现实中用3层循环就OK
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 学生成绩
{
internal class Program
{
static void Main(string[] args)
{
//在控制台中输入学生的学号及语文、数学、英语成绩,然后输出学生各科成绩信息(平均成绩和总成绩)
Console.Write("请输入本班的学生总数:");
int count = Convert.ToInt32(Console.ReadLine());//定义学生总数并强转。
int[,] achievement = new int[count, 4];//定义二维数组存储学生各科成绩
for (int i = 0; i < count; i++)
{
Console.Write("请输入第{0}个学生的编号:", i + 1);//i+1表示从第一个元素开始
achievement[i, 0] = Convert.ToInt32(Console.ReadLine());//二维数组第一个元素强转
Console.Write("请输入语文成绩:");
achievement[i, 1] = Convert.ToInt32(Console.ReadLine());//第一行第二列元素输入的语文成绩
Console.Write("请输入数学成绩:");
achievement[i, 2] = Convert.ToInt32(Console.ReadLine());//第一行第二列元素输入的语文成绩
Console.Write("请输入英语成绩:");
achievement[i, 3] = Convert.ToInt32(Console.ReadLine());//第一行第二列元素输入的语文成绩
}
Console.WriteLine("学生成绩结果如下:");
Console.WriteLine("—————————————————-");//主要是为了区分
Console.WriteLine("学生编号\\t语文成绩\\t英语成绩\\t平均成绩\\t总成绩");//双层for循环
for (int i = 0; i < achievement.GetLength(0); i++)//指定索引是0获取的行数
{
double sum = 0, ave = 0; //double类型变量记录总成绩和平均成绩
for (int j = 0; j < achievement.GetLength(1); j++) //获取数组列用GetLength方法指定索引为1
{
Console.Write(achievement[i, j] + "\\t\\t");//输出遍历到的元素
if (j > 0)//判断j>0计算总成绩
{
ave += achievement[i, j];
}
ave = sum / 3;//计算平均成绩
Console.Write(string.Format("{0:F2}", ave + "\\t\\t" + sum + "\\n"));//对平均成绩格式化后\\n输出换行
}
Console.ReadLine();
}
}
}
}
使用foreach语句遍历数组
遍历集合中的每一个元素,数组也是集合类型。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 进销存管理之数组遍历
{
internal class Program
{
static void Main(string[] args)
{
//使用字符串数组存储进销存管理系统的主要功能模块,然后使用foreach语句遍历并进行输出。
string[] strNames = { "进货管理", "销售管理", "库存管理", "系统设置", "常用工具" };
foreach (string str in strNames)
{
Console.WriteLine(str);
}
Console.ReadLine();
}//在集合或数组里面对迭代变量进行操作
}
}
对数组进行排序
从小到大:用Array类提供的sort方法进行排序,进行反转用Array类提供的Reverse方法实现反转。(反转不是逆向排序)
Array类提供的sort方法和Reverse方法可以对数组进行排序。
//从小到大
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 逆向排序
{
internal class Program
{
static void Main(string[] args)
{
int[] arr = { 22, 232, 133, 44, 5875 };
Array.Sort(arr);//调用Arraylist类传入sort方法
foreach (int i in arr)
{
Console.WriteLine(i);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 逆向排序
{
internal class Program
{
static void Main(string[] args)
{
int[] arr = { 22, 232, 133, 44, 5875 };
Array.Sort(arr);//调用Arraylist类传入sort方法
Array.Reverse(arr);//逆向排序
foreach (int i in arr)
{
Console.WriteLine(i);
}
}
}
}
数组排序算法 前面讲的Array类的sort方法和Reverse方法
冒泡排序算法–常用数组排序方法
概念:数据在数组中不断的向前移动最后达到一个有序数列目的。
基本思想:比较相邻两个元素值,如果满足条件就交换元素值,把较小元素移到数组前面,较大移到数组后面。
结构化流程图描述:输入一维数组定义一个临时变量temp(在交换数组元素值时候用到),变量i=0,i小于数组长度-1,j=i+1;j小于数组长度,比较两个值根据他们大小关系来交换两个元素的值,直到j大于数组长度再进行i++操作执行下一轮循环。直到i大于数组长度-1退出循环。–排序之后的数组。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 冒泡排序
{
internal class Program
{
static void Main(string[] args)
{
int[] arr = { 63, 4, 24, 1, 15 }; //定义一个一维数组
Console.WriteLine("初始数组:"); //输出原始数组
for (int i = 0; i < arr.Length; i++) //数组输出用for循环输出 外层循环控制排序轮数
{
Console.Write(arr[i] + " ");//输出原始数组
}
int temp;//定义变量存储原始值
for (int i = 0; i < arr.Length-1; i++)//进行外层循环 外层循环判断数组轮数到最后一轮不需要输出循环 这时候-1
{
for (int j = i + 1; j < arr.Length; j++)//内层循环定义数组中每个临近元素的大小,确定是否要交换位置
{
if (arr[i] > arr[j]) //内层循环判断 如果是逆序排序:>改为<
{
temp = arr[i];//记录元素值
arr[i] = arr[j];//j位置元素值赋值给i位置元素
arr[j] = temp;//temp临时变量的值赋值给j这个位置元素
//实现交换两个位置元素值功能
}
}
}
Console.Write("排序后的数组:");//循环遍历输出后就是排序后的数组
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");
}
Console.ReadLine();
}
}
}
选择排序算法–个头小或个头大的放在前面
个头小伙个头大的摆在前面或后面。
基本形式:将指定排序位置与其他数组元素分别对比,满足条件就交换元素值,满足指定条件元素与排序位置进行交换,排序好的会逐渐扩大,最后成为已经排序好的格式。
与冒泡排序优点:交换次数少很多,选择更快。

输入一个一维数组定义一个int类型变量i=0;判断i是否小于数组长度-1,外层循环用来控制循环轮数,条件满足定义int类型变量min默认值是遍历到的i的值,j=i+1;判断j小于数组长度,如果小于数组长度会把j位置的值和min位置的值进行比较,如果小于会把j赋值给min j++ 循环比较得到min最小值,遍历完内层循环后获取min位置元素值就是除了第一个元素外的最小的值,然后将最小位置的值与i的值进行交换,再i++进行第二次循环,最后得到一个有效的数组。
选择排序过程
选择排序:外层循环控制循环轮数,内层循环先把较大或较小的值提取出来,然后与i位置的值交换位置,进行下一次循环挑选剩余较大或较小的值再进行交换。最后输出排序后数组。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 选择排序实现过程
{
internal class Program
{
static void Main(string[] args)
{
int[] arr = { 63, 4, 24, 1, 15 }; //定义一个一维数组
Console.WriteLine("初始数组:"); //输出原始数组
for (int i = 0; i < arr.Length; i++) //数组输出用for循环输出 外层循环控制排序轮数
{
Console.Write(arr[i] + " ");//输出原始数组
}
int min;
for(int i = 0; i < arr.Length – 1; i++)
{
min = i;
for(int j = i + 1; j < arr.Length – 1; j++) //i小于数组长度减一
{
if(arr[j]< arr[min]) //内层循环过程小于改为大于—从大到小排序
{
min = j;
}
}
int temp = arr[min];
arr[min] = arr[i];
arr[i] = temp; //临时变量值赋给i
}
Console.Write("排序后的数组:");//循环遍历输出后就是排序后的数组
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");
}
Console.ReadLine();
}
}
}
ArrayList集合类
数组空间设置完后是固定的。

集合类就像一个容器, 相当于一个动态数组。
数组(巴士)是固定的,集合中数据可以随时添加、修改和删除。
C#中用ArrayList表集合
创建ArrayList对象
使用ArrayList类的构造函数创建对象。
主要操作:
添加: Add() –集合最后位置添加相应元素
Insert() –集合指定索引位置去添加一个元素
遍历:foreach
删除:Remove() –移出某个元素
RemoveAt() –参数类型里面是一个int类型参数来指定索引位置(删除指定索引位置的元素)
RemoveRange() –删除一定范围内的元素(第一个:删除要开始指定位置的索引;第二个:要删除几个元素。)
Clear() –清空ArrayList集合中的所有元素
查找:Contains() –查找集合中是否有这个元素
IndexOf() –查找某个元素在集合中第一次出现的索引
LastIndexOf() –查找某个元素在集合中最后一次出现的索引
创建ArrayList首先要加命名空间
Arraylist与数组区别:ArrayList里面可以存储不同类型元素,数组只能指定指定类型数组。
using System.Collections;添加命名空间
删除方法;Remove(); 删除要移除的对象

直接Remove找有没有5这个元素
list.RemoveAt(2); 2时在索引位置2删除指定的元素
list.Clear(); 没有参数 –清空list集合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ArrayList集合类
{
internal class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();//new关键字调用构造函数创建ArrayList集合类 //创建集合对象
list.Add("支付宝");//演示添加操作
list.Add("微信支付");
list.Add("云闪付");//通过Add方法向list集合添加三个元素
list.Insert(1, "pos机");//Insert方法 通过Insert方法插入pos机这个元素 剩下一次往后挪 第一个位置指定索引要插入的值
//list.Remove(5);//Remove移除 输出结果里5没有了
//list.RemoveAt(5);//移除索引位置5的元素 最大索引是4,索引超出范围不能运行
//list.Insert(2,5);//list集合存储元素类型可以不一样 索引位置2插入int类型值5运行会报错 遍历用字符串遍历出现类型转换错误 改为object类型 Arraylist存储的数据类型不一样,相对于数组来说好。
//list.RemoveAt(2);//改为2同样能把5删除掉
//list.RemoveRange(0, 2);//从0这个位置删除两个元素(只剩下微信支付和云闪付)
//list.Clear(); //没有参数–清空list集合 清空什么都输不出来 Clear方法删除list集合
foreach (object s in list)//查看是否添加上用foreach遍历集合 遍历用foreach
Console.WriteLine(s);//输出遍历集合对象
Console.ReadLine();
}
}
}
查找方法
bool list Contains:确定某个元素是否在集合中,返回值是布尔类型。如果找到了证明存在找到元素返回true,否则返回false 用布尔类型变量记录值
list集合里面查找元素是精确查找,里面一部分找不到。
LastIndexOf与IndexOf区别:方法使用是差不多的,都是找到的对应元素的索引,一个从前往后另一个从后往前。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ArrayList集合类
{
internal class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();//new关键字调用构造函数创建ArrayList集合类 //创建集合对象
list.Add("支付宝");//演示添加操作
list.Add("微信支付");
list.Add("云闪付");//通过Add方法向list集合添加三个元素
list.Insert(1, "pos机");//Insert方法 通过Insert方法插入pos机这个元素 剩下一次往后挪 第一个位置指定索引要插入的值
//list.Remove(5);//Remove移除 输出结果里5没有了
//list.RemoveAt(5);//移除索引位置5的元素 最大索引是4,索引超出范围不能运行
//list.Insert(2,5);//list集合存储元素类型可以不一样 索引位置2插入int类型值5运行会报错 遍历用字符串遍历出现类型转换错误 改为object类型 Arraylist存储的数据类型不一样,相对于数组来说好。
//list.RemoveAt(2);//改为2同样能把5删除掉
//list.RemoveRange(0, 2);//从0这个位置删除两个元素(只剩下微信支付和云闪付)
//list.Clear(); //没有参数–清空list集合 清空什么都输不出来 Clear方法删除list集合
//查找方法
bool bl = list.Contains("支付宝");
Console.WriteLine(bl); //返回T证明找到这个元素
//int index =list.IndexOf(""); //表示找到的这个元素的索引 支付宝索引位置是0
int index = list.LastIndexOf("支付宝"); //找支付时-1,没找到这个元素 LastIndexOf从后往前找 不分前后都是找对应位置索引
foreach (object s in list)//查看是否添加上用foreach遍历集合 遍历用foreach
Console.WriteLine(s);//输出遍历集合对象
Console.ReadLine();
}
}
}
使用List.Add();方式添加输入到控制台窗体里面
通过Add方法向list集合里面添加三个元素

Insert方法:第一个指定索引,第二个指定要添加元素的值。 list元素集合类型可以不一样(改为object类型才对)
添加元素:Add方法与Insert方法
删除元素
list.Remove; 删除要移除的对象
移除5 输出的5里面就没有了。如果变At(移除索引位置5的元素)
list集合:清空输入
Hashtable(哈希表)
集合类型,键值队集合。
Key:键 Value:值
常用属性:Count属性(获取哈希表中键值队的数量)
常用方法:Add(两个参数:K和V)
Remove(Object)
Contains/ContainsKey(Object key)–使用一样(参数都是object类型的Key) ContainsValue(Object value)–根据某个值查找,参数是value值
以上涵盖对哈希表添加、删除和查找操作。
存完数据后查看哈希表有没有存入这个数据:获取哈希表中的值后需要用到DictionaryEntry结构–可以获取哈希表中的键值。
Hashtable也是集合类,需要添加using System.Collections; 命名空间
通过构造函数创建哈希表
通过Add方法添加键值队组合
通过Remove方法删除指定键
Contains和ContainsKey)方法按照指定的键是否查找存在某个元素
ContainsValue–按照特定的值来确定哈希表是否存在这个值
遍历哈希表使用DictionaryEntry结构来遍历。
遍历完成后输出值用entry.Key和entry.Value 这个结构
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace 哈希表
{
internal class Program
{
static void Main(string[] args)
{
Hashtable hashtable = new Hashtable();//创建Hashtable对象 使用Hashtable构造函数可以创建Hashtable类的对象
hashtable.Add(1, "小王");//通过哈希表添加元素
hashtable.Add(2, "小刘");
hashtable.Add(3, "小赵");
hashtable.Remove(2);//删除2这个人 哈希表有2个键值队
bool bol=hashtable.Contains(2);//查找2这个键 指定要查找的键
Console.WriteLine(bol);
bool b13 = hashtable.ContainsValue(1);//指定要查找的值,根据值查找 //改为小王返回T,在哈希表中找到键值队组合中值为小王的元素,返回T
Console.WriteLine(b13); //哈希表里有键无值返回F
Console.WriteLine(hashtable.Count);//输出属性 查看有几对键值队 添加3对键值队集合
foreach (DictionaryEntry entry in hashtable) ;//遍历哈希表输出键值队集合
//Console.WriteLine(entry.Key+" "+entry.Value);//使用Remove方法删除哈希表中指定键的键值队组合
Console.ReadLine();
}
}
}

