链表--笔记


链表

知识点摘于b站教程视频: https://www.bilibili.com/video/av16869217?from=search&seid=12191125613016121321

 

b站教程视频有些繁琐。。。只看这篇文章链表入门应该可以理解接受

1.链表是存在于堆内存,存放在不连续的存储空间,在这些不连续的存储空间使用指针去作为一个索引。

 

 a) 链表的结构体

 

struct Student{
int num;//学号  数据域
char name[10];//姓名  数据域
struct Student *pnext;//表示这个指针指向下一个节点(即下一个结构体)  指针域
};

p是指针   不断用这个结构体的指针去指向下一个结构体,这就是一个链表。

 

b)节点是什么?

链表是由节点组成的,上图中每个结构体就是链表的节点。

 

小tips:

typedef struct Student{
int num;//学号
char name[10];//姓名
struct Student *pnext;//表示这个指针指向下一个节点(即下一个结构体)
}STU;

//c语言中,如果加上了第一句的typedef ,STU就是一种数据类型(相当于struct Student、
)若没有加typedef ,STU只是一个变量

//在c++中 ,Student可以直接作为数据类型。

 

2.两种链表

 

 

3.动态内存的使用(链表)

STU *pStu=NULL;  //相当于struct Student *pStu
pStu =(STU*)malloc(sizeof(STU)); //就是开辟一个节点

free(pStu);

 

4.创建链表头结点:

STU* CreateList()
{
STU *P=(STU*)malloc(sizeof(STU));
P->pnext=NULL; //头结点指向为空 (此时还不知道头结点的下一个指向谁) 为保证安全性,赋值为空

return P;

//不需要给num和name赋值,因为是头结点。
}

5.添加节点(按输入顺序添加节点)

添加一个节点

#include<stdio.h> #include<stdlib.h> typedef struct Student{ int num;//学号
    char name[10];//姓名
    struct Student *pnext;//表示这个指针指向下一个节点(即下一个结构体)
}STU; //创建链表的头结点
STU* CreateList() { STU *P=(STU*)malloc(sizeof(STU)); P->pnext=NULL; return P; } //添加节点
void addNode(STU *P ) { STU *pNew=NULL;//重新定义一个指针
    pNew=(STU*)malloc(sizeof(STU));//为新的指针开辟一块内存
    printf("请输入学号:"); scanf("%d",&pNew->num); printf("请输入姓名:"); scanf("%s",pNew->name); pNew->pnext=NULL;//为了安全,把指针指向定为空
 P->pnext=pNew;//连接起来
} int main(){ STU* pStu = NULL;//定义一个指针,接受链表的首地址
    pStu=CreateList();//头结点
 addNode(pStu);//添加一个节点 只添加了一个
 printf("%d\t%s\n",pStu->pnext->num,pStu->pnext->name);//打印添加的节点


    return 0; }

添加n个节点(人为控制添加的数量)

这个是初始状态,形参指针P指向头结点。

 

 

创建临时变量pNew,赋值后,此时令pNew=P->pNext,完成结点之间的连接

 

 

再令P指向新的节点

 

 

再往下举一个例子。

在for循环内创建一个新的pNew

 

 

给pNew赋值后,此时P指向第二个结点,令此时的pNew=P->pNext,完成结点之间的链接。

 

 

 

再令P指向新创建的节点。往后以此类推,形成链表。

 

 实现代码如下:

其中,addNode不一定非要输入n个,可以自己添加限制条件,例如num==0时结束输入

 1 #include<stdio.h>  2 #include<stdlib.h>  3  4 typedef struct Student  5 {  6 int num;//学号  7 char name[10];//姓名  8 struct Student *pnext;//表示这个指针指向下一个节点(即下一个结构体)  9 } STU; 10 11 //创建链表的头结点 12 STU* CreateList() 13 { 14 STU *P=(STU*)malloc(sizeof(STU)); 15 P->pnext=NULL; 16 return P; 17 } 18 19 //添加节点 人为控制添加的个数 20 void addNode(STU *P ) 21 { 22 STU * pNew=NULL; 23 int n;//当前要加入的节点的数量 24 scanf("%d",&n); 25 for(int i=0; i<n; i++) 26  { 27 pNew=(STU*)malloc(sizeof(STU)); 28 printf("请输入学号:"); 29 scanf("%d",&pNew->num); 30 printf("请输入姓名:"); 31 scanf("%s",pNew->name); 32  pNew->pnext=NULL;//尾节点设置为空 这个非常重要 33 34 P->pnext=pNew;//连接起来 35 P=P->pnext; 36  } 37 } 38 39 int main() 40 { 41 STU* pStu = NULL;//定义一个指针,接受链表的首地址 42 pStu=CreateList();//头结点 43 44 addNode(pStu);//添加n个节点 45 46 printf("%d\t%s\n",pStu->pnext->num,pStu->pnext->name);//打印第二个节点的内容 47 48 49 return 0; 50 }

 

6.遍历  打印出所有的信息

 

代码如下:

1 void PrintAll(STU *P) 2 { 3     P=P->pnext;//P指向第一个有数据的节点
4     while(P!=NULL) 5  { 6         printf("%d\t%s\n",P->num,P->name); 7         P=P->pnext; 8  } 9 }

 

 

下面讲,按输入顺序的逆序插入节点(即从中间插入节点)

这里头结点用head代替比较明显,前面头结点用的是pStu,但是懒得重新再画图了。。。。

 

创建新节点pNew

第一步

 

再进行一步相同的操作。

由于head->pnext指向先创建的pNew,那么令第二次创建的pNew->pnext=head->pnext,而head->pnext又指向先创建的pNew,于是先创建的pNew和后创建的pNew就连接起来了。

然后令head->pnext=pNew,指向后创建的pNew。

 

 

那么这三个就形成了如下的链表:

 

 

 

练习题见随笔---链表简单练习题2


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM