数组的不足
我们之前用的数组也是一种数据结构,数组是顺序存储的,数组逻辑关系上相邻的两个元素在物理位置上也相邻,这就导致了在对数组进行插入或删除操作时,需移动大量数组元素,并且数组的长度是固定的,而且必须预先定义,数组的长度难以缩放,对长度变化较大的数据对象要预先按最大空间分配,使存储空间不能得到充分利用。
链表的优点
链表存储结构是一种动态数据结构。
它包含的数据对象的个数及其相互关系可以按需要改变。
存储空间是程序根据需要在程序运行过程中向系统申请获得。
不要求逻辑上相邻的元素在物理位置上也相邻。
没有顺序存储结构所具有的弱点。
链表
链表是指将若干个数据项按一定的原则连接起来的表。链表中每一个数据称为节点。链表连接的原则是: 前一个节点指向下一个节点;而且只有通过前一个节点才能找到下一个节点。
相信在很多地方都看到上面这么一段话,不理解没关系,我们一边看图一边解释。
上面这段抽象的概念相信大家都能明白,问题在于真正去写代码的时候,你就会发现,其实你只是看明白而已。
我学了链表两个月,一直不明白到底这个链表是怎么建立起来的,直到老师开讲,我才懂。
我相信,只有结合代码实现来讲解才能明白。
首先数组之所以能够随机访问存储,是因为数组是顺序存储的,但这也导致了数组删除插入很麻烦,因为人家已经安排好位置了,不能随便改变。
而链表不需要顺序存储,每一块存储元素的地方只要能知道下一个在哪里就可以了。
链表必须用上结构体,结构体包含两种成员,一种是想要存储的数据类型,一种是用来指向下一个节点的指针。
一切看代码解析:
#include<iostream>
using namespace std;
struct list//创建一个简单的链表节点
{
int num;//只是存储一个数
list *next;//指向下一个节点的指针,链表的关键
};
int main()
{
list *head=NULL,*chain=NULL,*data=NULL;//头指针用来记录这个链表的位置,另外两个指针用来推进节点的创建和连接
//链表数据的输入
while(1)
{
data=new list;//首先分配一块内存
cin>>data->num;//读入数据并存储
if(head==NULL)//如果是第一个,那么要让头指针指向它
head=data;
else//如果不是第一个,那么就让上一个节点的指针成员指向它
chain->next=data;
chain=data;//让这个节点成为上一个节点
data->next=NULL;//表示尾节点
if(getchar()=='\n')//如果按下回车就不读了,不然就一直装
break;
}
//链表数据的输出
data=head;//找到链表的位置
while(data)//如果不是尾节点的指针,那就输出
{
cout<<data->num<<' ';
data=data->next;//推进
}
//链表内存释放
data=head;//找到链表位置
while(data)//如果不是到尾了,那就继续释放
{
chain=data->next;//先推进,不然先释放的话,后面的就找不到了
delete data;
data=chain;
}
}