当前位置:   article > 正文

C语言学习之链表_struct node *p

struct node *p

今天学习了链表,第一次接触,感觉很不适应,写此博客梳理巩固一下。

我感觉,链表其实就是结构体+指针的运用(个人理解)。操作起来比数组简单很多。

首先创建一个结构体:

  1. struct node
  2. {
  3. int data;
  4. struct node *next;
  5. };

其中data用来存放整数,功能和数组一样。而其中的struct node *next则是用来储存下一个结点的地址。

什么是结点?

结点我这里是指包含一个数据和下一个结点地址的东西。结点1(数据,结点2地址)->结点2(数据,结点3地址)->……这就是结点。

现在尝试着回忆创建一个链表:

  1. struct node *head;
  2. head = NULL;
head指向链表的最开始,因为链表还没有建立,所以head为空,也可以理解为指向一个空结点。

现在我们创建第一个结点,并用临时指针p指向这个结点:

  1. struct node *p;
  2. p = (struct node*)malloc(sizeof(struct node));
使用mollac动态申请一个空间,用来存放结点,然后使用指针p指向他。

接下来,我们来设置这个新创建结点的所包含的内容(data和地址):

  1. scanf("%d",&a);
  2. p->data=a;
  3. p->next=NULL;
这里应该很好理解,将输入data。

然后要创建头指针,也就是进行一个判断,是否是第一个结点,作用是方便以后从头遍历整个链表:

  1. if(head == NULL) head=p;
  2. else q->next=p;
如果这是第一个创建的结点,那么头指针指向这个结点;如果这不是第一个创建的结点,那么将上一个结点的后继指针指向当前结点。

最后,将指针q也指向当前结点,因为,一会p将会指向新创建的结点:

q=p;

完整代码:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. struct node
  4. {
  5. int data;
  6. struct node *next;
  7. };
  8. int main(){
  9. struct node *head,*p,*q,*t;
  10. int i,n,a;
  11. scanf("%d",&n);
  12. head = NULL;//头指针初始为空
  13. for(i=0;i<n;i++){
  14. scanf("%d",&a);
  15. //申请一个动态空间,用来存放结点,并临时指针p指向这个结点
  16. p = (struct node *)malloc(sizeof(struct node));
  17. p->data=a;
  18. p->next=NULL;
  19. if(head==NULL) head = p;//如果这是第一个创建的结点,就指向自己。
  20. else q->next=p; //如果不是,让上一个结点的后继指针指向当前结点。
  21. q=p;//指针q指向当前结点
  22. }
  23.     t=head;
  24.     while(t!=NULL){
  25.         printf("%d ",t->data);
  26.         t=t->next;//继续下一个结点
  27.     }
  28.     
  29.     return 0;
  30. }
这样就达到了和数组同样的功能。

输入:

9

2 3 5 8 9 10 18 23 32

输出:

2 3 5 8 9 10 18 23 32

现在要进行进阶:在表中插入一个数。

2->3->5->8->9->……变化为2->3->5->6->8->9->……

所以,应该从头开始遍历,和输出一样。当指针p的下一个结点的值大于6的时候,将6插入中间:

  1. int flag;
  2. scanf("%d",flag);
  3. t=head;
  4. while(t!=NULL)
  5. {
  6. if(t->next==NULL||t->next->data > flag)
  7. {
  8. p = (struct node *)malloc(sizeof(struct node));
  9. p->data=flag;
  10. p->next=t->next;//新增结点的后继指针指向当前结点的后继指针所指向的结点
  11. t->next=p;//当前结点的后继指针指向新增结点
  12. break;
  13. }
  14. t=t->next;//继续下一个结点
  15. }
flag就是想要添加的数。下面展示完整代码:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. struct node
  4. {
  5. int data;
  6. struct node *next;
  7. };
  8. int main(){
  9. struct node *head,*p,*q,*t;
  10. int i,n,a;
  11. scanf("%d",&n);
  12. head = NULL;//头指针初始为空
  13. for(i=0;i<n;i++){
  14. scanf("%d",&a);
  15. //申请一个动态空间,用来存放结点,并临时指针p指向这个结点
  16. p = (struct node *)malloc(sizeof(struct node));
  17. p->data=a;
  18. p->next=NULL;
  19. if(head==NULL) head = p;//如果这是第一个创建的结点,就指向自己。
  20. else q->next=p; //如果不是,让上一个结点的后继指针指向当前结点。
  21. q=p;//指针q指向当前结点
  22. }
  23. //想要添加的数
  24. int flag;
  25. scanf("%d",flag);
  26. t=head;
  27. while(t!=NULL)
  28. {
  29. if(t->next==NULL||t->next->data > flag)
  30. {
  31. p = (struct node *)malloc(sizeof(struct node));
  32. p->data=flag;
  33. p->next=t->next;//新增结点的后继指针指向当前结点的后继指针所指向的结点
  34. t->next=p;//当前结点的后继指针指向新增结点
  35. break;
  36. }
  37. t=t->next;//继续下一个结点
  38. }
  39. //输出链表中的所有数
  40. t=head;
  41. while(t!=NULL){
  42. printf("%d ",t->data);
  43. t=t->next;//继续下一个结点
  44. }
  45. return 0;
  46. }

现在可以测试一下输出结果了。

输入:

5

1 6 7 8 9

输出:

1 2 3 7 8 9

这就是链表的基本应用。

为什么要使用链表?

链表可以根据使用情况来申请空间,而不是像数组一样需要定义大小。并且相比较于数组,链表可以方便的添加和删除数。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/825776
推荐阅读
相关标签
  

闽ICP备14008679号