在数组的使用过程中,可以发现有很多的缺点,比如数组的占用内存一旦定下来就很难再去改变、在一个完整的数组中不可能再添加或删去元素。正是这一些性质 ,使得链表的存在成为了必要的,乃至于对后面的数据结构的学习都占有很大的比重。
链表简介
链表由链节相连构成,每一个链表之间由指针连接,因此,链节分为数据区和指针区。而结构体的性质刚好适合作为链节,因此我们习惯使用结构体进行链表额度创建。
链表是由指针相连的,因此不需要提前确定好所有元素存放的位置,而是只需要在创建新链节的时候开辟新内存空间即可。也正是这样的“随意性”,链表在存储数据时速度非常快,而读写时速度较为缓慢。
链表将元素分散在了内存当中,使得数据密度大大降低,但是也就出现了一个问题,那就是如果不作处理的话,在删去一个链节之后,就会让后面的链节丢失在内存中,这样的情况就会造成数据的损失,所以在删除一个链节之前,要先对指针的连接进行处理。
创建链表的代码
创建链表需要使用迭代的方式生成下一个链节;
#include<iostream>
using namespace std;
typedef struct Lnode
{
int data;
Lnode* next;//利用迭代的方式生成指向下一个链节的指针
}*Linklist;//创建指向结构体的指针
void creatList(Linklist L, int length)
{
int i = 0;
Linklist p1, p2;
p1 = p2 = L;
while (i < length)
{
p1 = new Lnode;//利用new关键字声明指针,创建新链节
p1->data = i + 1;//写入data
p2->next = p1;//声明下一个p1链节的指针与上一个p2相连,
//p2依然在上一个链节的指针区即*next部分,
//p1则是到内存中开辟新空间创建了一个新的链节
p2 = p1;//p2移入下一个链节
i++;
}
p2->next = NULL;//最后一个链节的next指针指向空
}
int main()
{
Linklist L = new Lnode;
L-> data = 0;
L->next = NULL; //在操作指针前记得初始化
creatList(L, 4);
Linklist p;
p = L;
while (p->next)
{
cout << p->data << endl;
p = p->next;
}
cout << p->data << endl;
return 0;
}
以上的操作就可以生成一个0~4的链表并打印。
链表的删除功能
void delnode(Linklist L)
{
Linklist tmp, p;
p = tmp = L;
while (p->next)
{
tmp = p->next;
delete p;
p = tmp;
}
delete p;
}
先创建一个临时指针将被删链节的前一个和后一个连接起来,然后将指向这个被删链节的指针删去就完成了一次链节的删除。
除了上面介绍的单向链表之外,还有一种双向链表,就可以让程序从两个不同的方向进行遍历。