欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

链表:创建一个简单的链表并输出链表内容

程序员文章站 2022-06-15 15:06:20
链表的专业术语: 首节点:存放第一个有效数据的节点 尾节点:存放最后一个有效数据的节点 头结点: 1.头结点的数据类型和首节点的数据类型是一模一样的 2.头结点是首节点前面的那个节点 3.头结点并不存放有效数据 4.设置头结点的目的是为了方便对链表的操作 头指针:存放头结点地址的指针变量 用一张图片 ......

链表的专业术语:

  首节点:存放第一个有效数据的节点
  尾节点:存放最后一个有效数据的节点
  头结点
      1.头结点的数据类型和首节点的数据类型是一模一样的
      2.头结点是首节点前面的那个节点
      3.头结点并不存放有效数据
      4.设置头结点的目的是为了方便对链表的操作
  头指针:存放头结点地址的指针变量

用一张图片来展示链表的基本框架:

链表:创建一个简单的链表并输出链表内容

⭐尾节点的指针域为空,可以表示为null

⭐想要确定一个链表,需要最基本的信息是头指针,之后的信息都可以通过头指针找出来。

接下来编写程序,只有用实际的例子,才能更全面的理解!

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 struct node                          //定义一个链表结构 
 4 {
 5     int data;                        //链表节点的数据 
 6     struct node * pnext;             //链表节点指向下一个节点的指针 
 7 };
 8 int i;
 9 struct node * create_list(void);     //创建链表的函数声明 
10 void traverse_list(struct node *);   //打印链表的函数声明 
11 int main()
12 {
13     struct node * phead = null;     //先给头指针赋值为null 
14     phead = create_list();          //调用链表创建函数,并将头指针的值赋给phead 
15     traverse_list(phead);           //打印链表
16     return 0;
17 }
18 struct node * create_list(void)     //创建链表的函数
19 {
20     int len;                        //链表的节点数 
21     int val;                        //链表节点中数据域的值 
22     struct node * phead=(struct node *)malloc(sizeof(struct node));  //动态分配头结点的内存 
23     if(phead == null)
24     {
25         printf("内存分配失败,程序终止!\n");
26         exit(-1);
27     }
28     struct node * ptail = phead;                        //定义一个尾节点指针,将phead的值赋给它 
29     ptail->pnext = null;                                //尾节点的指针域一定为空 
30     printf("请输入您需要生成的链表节点的个数:len =");
31     scanf("%d",&len);
32     for (i=0;i<len;i++)
33     {
34         printf("请输入第%d个节点的值:",i+1);
35         scanf("%d",&val);
36         struct node * pnew=(struct node *)malloc(sizeof(struct node));  //动态分配新节点的内存
37         if(pnew== null)
38     {
39         printf("内存分配失败,程序终止!\n");
40         exit(-1);
41     }
42         pnew->data = val;       //把输入的值传给*pnew数据域 
43         pnew->pnext = null;     // *pnew是新的尾节点,所以 pnew->pnext应该为空
44         ptail->pnext = pnew;    //把*pnew的地址传给ptail->pnext指针域,等效于*ptail.pnext=pnew
45                                 //第一次的ptail->pnext = pnew相当于把首节点的地址给了头结点
46                                 
47         ptail = pnew;           48                                 //执行此操作,*pnew就变成了新的*ptail 
49                                 //之后的ptail = pnew则是让最后一个与上一个节点连接上     
50      } 
51     return phead;               //返回 phead的值 
52 }
53 void traverse_list(struct node * phead)  //遍历链表 
54 {
55     struct node * p = phead->pnext;      //定义一个指向下一个节点的指针 
56     while(p!=null)                       //尾节点的指针域一定是null,如果非null,则继续打印 
57     {
58         printf("%d\t",p->data);
59         p = p->pnext;                    //下一个节点的地址赋值给p 
60     }
61     return;                              //循环结束 
62 }

在这个程序中,我对44行和47行的代码思考了很久

最开始总觉得有了44行代码 ptail->pnext = pnew ,47行的代码 ptail = pnew 重复了,删去之后,发现不行,下面对两者的区别进行画图解析:

链表:创建一个简单的链表并输出链表内容

 

 

第1步:*ptail的地址就是phead,所以phead指向*ptail,另外,新创建的*pnew还没有赋值。

第2步:将val赋值给*pnew的数据域,null赋值给*pnew的指针域,并把*pnew的地址传给*ptail的指针域

第3步:把*pnew的地址赋值给ptail,让*pnew变成新的*ptail

整个过程大致就是如此,理解了,其实也不难,要掌握更多的知识,需要进一步学习数据结构。