1 . 数组是什么?
数组是具有某种相同特征的对象的集合。比如:int a[10]是一个存放10个整型数字的集合,double a[10]是一个存放10个双精度数字的集合等。数组其实是一个数据结构,因为当我们在声明并定义一个数组的时候,程序就会在内存中为我们申请一个连续的N*(sizeof ( type ))大小的空间。
1 . 1 存放的位置
栈:我们在函数(方法)中定义一个变量的时候,程序就会在栈上开辟一段空间,生命周期结束后,程序会自动释放掉开辟的空间。
堆:我们使用new / gcnew中定义一个变量的时候,程序就会在堆上开辟一段空间,生命周期结束时,需手动释放内存空间。
1 . 2 使用的方法
固定大小的一维数组:元素数据类型 数组名称[数组大小] 例:int a[20]
固定大小的二维数组:元素数据类型 数组名称[数组大小] 例:int a[20][20]
动态大小的一维数组:C++ : int *a = new a[size] C : int *a = (int*)malloc(sizeof(int)*Number) ||||| 当使用结束后,delete[] a;
动态大小的二维数组:
#include <iostream>
using namespace std;
int main()
{
// b,c分别是行、列
int b,c;
cin>>b>>c;
int **a = new int*[b];
for(int i = 0;i<b;i++)
a[i] = new int[c];
// dispose
for(int i = 0;i<b;i++)
delete[] a[i];
return 0;
}
1 . 3 使用的场景
假设我们现在有一个需求,要在一维数组的中间位置插入一个值,那么你首先需要找到这个位置,并将这个位置开始至结束的所有值都向后移动一个数据类型大小的单元,删除的情况同样如此麻烦。由此可以得出:当我们需要对数据集合集合进行频繁的插入、删除等操作的时候,我们尽量避免使用数组来进行操作。当我们在频繁的取值、赋值计算的时候,由于数组是连续的,因此通过索引查找到某一个值、或将数据写回都是是非常迅速。
1 . 4 注意的地方
1)对于非动态数组,读写数据时注意。如:int a[10]是固定大小为10的整型数组,索引值最大为9(从0开始,PASCAL除外),索引超过9编译器会报错。
2)对于动态数组,数组的使命周期结束后,需要手动将内存释放。
3)对于数组的大小,有两种情况,一个是sizeof(a),表示数组a设定的元素个数,一个是strlen(a),表示数组中存储的数据的元素个数。
2 . 链表是什么?
链表也是一种数据结构,是一种链式存储数据的数据结构,链表并不要求存储的数据的内存地址都是连续的,可以连续,也可以不连续。
2 . 1 链表的组成
一般的单链表结构由以下几个要素组成,其中主要包括:头指针、结点、NULL
2 . 2 到底有什么优势?
在上边的数组中已经介绍了,数组其实是一个偏科生,比较擅长取值赋值。而链表其实也是一个偏科生,比较擅长插值、删值等。一般情况下,我们在项目中,遇到需要定义的数据结构时,可以根据实际项目的需求,自行选择究竟是使用链表,还是数组。对于C++,我们可能并不需要自己去从0开始构造一个单链表的数据结构,而去使用有一些具有链表性质的容器。比如:vector等。但是基于对技术的深入探索,我们还是需要在底层去了解链表结构的具体实现,甚至去重写自己的链表结构。
2 . 3 都有哪些类型?
链表:单链表、双链表、循环链表等。
单链表:每个结点只有一个指针指向下一个结点。
双链表:每个结点有两个指针,一个指针指向上一个结点的地址,一个指针指向下一个结点的地址。(迅速的查找当前结点的上一个结点和下一个结点的数据)
循环链表:链表的最后一个结点的指针域指向头结点,形成一个环状的数据结构。