*****参照《大话数据结构》整理*****
一、基本要素概念明析
1.指针
指针也就是内存地址 ,指针变量是用来存放内存地址的变量(按照百度定义,进行下面的介绍)
2.结构体
结构体是C语言中一种重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以具有不同的类型。结构体通常用来表示类型不同但是又相关的若干数据。
3.结点
一个包括数据域与指针域的结构体
4.头指针
为了方便此处将头指针理解为头指针变量(虽然与1好像有矛盾)
5.头节点
链表头部的结点,数据域通常用来存放链表长度
6.首元结点
头结点后的第一个结点
二、基本要素再说明
1.结点的构造
//typedef int ElemType;//这里将int 定义为 ElemType (数据类型)以代表不同的数据
typedef struct Node{
ElemType data;
Struct Node *next;
/* 这里两个指针变量其实是同一类型的,都指向Node结点,
LinkList 用于定义一个链表的名字,提高可读性
比如 LinkList L 即 一个叫做 L 的链表(其实L就是head)
*/
} Node; //typedef 结点
typedef Node * LinkList; // typedef Node型指针
2.头指针(head)
此处按头指针为指针变量进行说明
总之就是指向第一个结点的指针,不管是头结点,还是首元结点
3.头结点
在链表的首位,为了方便添加,也可以不带头结点,数据域通常无意义也可用来存放链表长度,指针域指向首元结点。
好处:使得链表首元结点的插入和删除操作同其它结点操作相同。
三、单链表的创建
1.头插法
顾名思义:将结点从链表的头部插入,即每插入一个结点,取代首元位置。如果有头结点,每次插在头结点之后
图示:
第一个结点插入完成!然后重新申请一个结点,p指向新的结点重复操作。
代码如下:
void CreatListHead(LinkList &L,int n){
//注意这里&L用的是C++引用,可以理解为把实参传到函数中,
//也可用*L达到相同效果
LinkList p; //定义p指针
int i;
srand(time(NULL)); //利用随机种子给data域赋值
L=(LinkList)malloc(sizeof(Node)); //头指针拿到头结点的地址
L->next = NULL; //头结点的 next 置为NULL
for(i=0;i<n;i++){
p = (LinkList)malloc(sizeof(Node));
p->data = rand%100+1;
p->next = L->next;//将p指向的结点的next指向头结点的next 所指向的结点
L->next = p; //头结点的next指向p
}
}
2、尾插法
顾名思义,每次将申请到的结点插入到链表后面
如图:
即:头不动,r随着链的增长依次后移
3.代码如下
void creatListTail(LinkList &L,int n){
Linklist p,r; //定义两个指向结点的指针
int i;
srand(time(NULL)); // 利用随机种子给data域赋值
L = (LinkList)malloc(sizeof(Node));
r = L; //r与L共同指向头结点
for(int i;i<n;i++){
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100+1;
r->next = p;
r = p; //r后移
}
r->next = NULL; //尾结点指针域置空
}
四、头插尾插的区别
头插:将输入的数据插入到队头。从头结点往后遍历链表得到的是输入的数据的逆序排列。
尾插:将输入的数据插入到队尾。从头结点往后遍历链表得到的是输入的数据的顺序排列。
若有不足之处,还请不吝赐教