为什么使用链表
数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性。但数组也同样存在一些弊病。如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要3 0个大小的数组,有时需要5 0个数组的大小,难于统一。我们只能够根据可能的最大需求来定义数组,常常会造成一定存储空间的浪费。
我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要。链表就是我们需要的动态数组。它是在程序的执行过程中根据需要有数据存储就向系统要求申请存储空间,决不构成对存储区的浪费。
链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表,我们今天只介绍单链表。
单链表
单链表由一系列结点(链表中每一个元素称为 结点(node)) 组成,每个结点包括两个部分:一个是存储数据元素的 数据域(data) ,另一个是存储下一个结点地址的 指针域(next) 。链表按此结构对各节点的访问需从链表的 头(head) 找起,后续节点的地址由当前节点给出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL。如图:
上图还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存的当前情况,既可以连续分配地址,也可以跳跃式分配地址。
一.单链表的定义
struct node//结点
{
int data;//数据域
node *next;//指针域
};
二.基本操作
1.创建单链表
#include<bits/stdc++.h>
using namespace std;
struct node//结点
{
int data;//数据域
node *next;//指针域
};
node *head,*p,*q;
int main()
{
head=new node;//生成一个新结点,作为头结点
p=new node;//生成一个新结点
head->next=p;
p->next=NULL;//这两句就生成了一个有两个结点的完整的单链表
for(int i=1;i<=10;i++)
{
q=new node;//生成一个新结点
q->data=i*100;//给结点的数据域赋值
q->next=NULL;
p->next=q;
p=