当前位置:   article > 正文

C语言数据结构(链表)_c语言链表数据结构

c语言链表数据结构

一、什么是链表

链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成。相对于线性表顺序结构,操作复杂。

二、链表的作用

实现数据元素的存储按一定顺序储存,允许在任意位置插入和删除结点,包括单向结点,双向结点,循环接点。

三、静态创建链表(包含计算链接节点总数、查找链表节点、遍历链表信息)

  1. #include <stdio.h>
  2. struct Test
  3. {
  4. int data;
  5. struct Test *next;//定义结构体指针,指向结构体里面的元素
  6. };
  7. void printLink(struct Test *head)
  8. {
  9. struct Test *point;//定义临时结构体指针
  10. point = head;//指向链表的头
  11. while(point != NULL){
  12. printf("%d ",point->data);
  13. point = point->next;
  14. }//遍历链表
  15. putchar('\n');
  16. }
  17. int getLinkTotalNum(struct Test *head)
  18. {
  19. int cnt = 0;//定义临时变量记录链表节点数
  20. while(head != NULL){
  21. cnt++;
  22. head = head->next;
  23. }//遍历链表
  24. return cnt;//返回节点数
  25. }
  26. int findLink(struct Test *head,int data)
  27. {
  28. while(head != NULL){
  29. if(head->data == data){
  30. return 1;
  31. }
  32. head = head->next;
  33. }
  34. return 0;
  35. }
  36. int main()
  37. {
  38.     //初始化结构体
  39. struct Test t1 = {1,NULL};
  40. struct Test t2 = {2,NULL};
  41. struct Test t3 = {3,NULL};
  42. struct Test t4 = {4,NULL};
  43. struct Test t5 = {5,NULL};
  44.     //链接节点
  45. t1.next = &t2;
  46. t2.next = &t3;
  47. t3.next = &t4;
  48. t4.next = &t5;
  49. printf("use t1 to printf three nums:\n");
  50. //printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);
  51. printLink(&t1);//打印链表数据
  52. int ret = getLinkTotalNum(&t1);//调用查找链表节点函数
  53. printf("total num = %d\n",ret);
  54. ret = findLink(&t1,3);//查找链表是否存在节点3
  55.     //返回值判断
  56. if(ret == 0){
  57. printf("no 3\n");
  58. }else{
  59. printf("have 3\n");
  60. }
  61. return 0;
  62. }
四、链表的插入
  1. 从指定节点后方插入新节点(节点后插法)

实现步骤分为两步:1.1 找到要插入的节点位置

2.1 把新节点链接要插入节点位置的下一个,再把插入节点位置的下一个链接新节点

  1. //函数包含三个形参(链表头,插入节点位置,新节点)
  2. int insertFromBehind(struct Test *head,int data,struct Test *new)
  3. {
  4. struct Test *p=head;//定义临时结构体指针指向链表头
  5. //遍历链表
  6.         while(p !=NULL){
  7.     if(p->data==data){ //判断插入新节点位置
  8.     new->next=p->next;//把新节点的尾链接要插入节点的下一节点
  9.     p->next=new;//把插入节点的下一个链接新节点
  10.     return 1;
  11. }
  12. p=p->next;
  13. }
  14. return 0;
  15. }

2、从指定节点前方插入新节点(头插法)

实现步骤分为两种:1.1 直接在链表头插入

2.1 在链表中间节点插入

2.1.1 找到节点的下一个为插入位置的目标节点,把新节点接入目标节点的下一个,再把目标节点的下一个链接新节点

  1. struct Test* insertFromForward(struct Test *head,int data,struct Test *new)
  2. {
  3. struct Test *p=head;//定义临时结构体指针指向链表头
  4. //直接在链表头插入
  5. if(p->data==data){
  6. new->next=head;//把新节点的下一个直接链接链表头
  7. return new;//链表头返回新节点
  8. }
  9. //在链表中间节点插入
  10. while(p->next != NULL){
  11. if(p->next->data==data){//找到节点的下一个为插入位置的目标节点
  12. new->next=p->next;//把新节点接入目标节点的下一个
  13. p->next=new;//再把目标节点的下一个链接新节点
  14. printf("insert success\n");
  15. return head;//返回链表头
  16. }
  17. p=p->next;
  18. }
  19. printf("insert no\n");//没找到插入位置,插入失败
  20. return head;//返回链表头
  21. }
五、链表的删除
  1. 从指定节点后方插入新节点(节点后插法)

实现步骤分为两种:1.1 直接在链表头删除

2.1 在链表中间节点删除

2.1.1 找到节点的下一个为删除位置的目标节点,再把目标节点的下一个链接目标节点的后第二个

  1. struct Test* delectNode(struct Test *head,int data)
  2. {
  3. struct Test *p=head;
  4. //直接在链表头删除
  5. if(p->data == data){
  6. head=head->next;//把链表头链接到链表头的下一个
  7. free(p);//释放删除节点
  8. return head;
  9. }
  10. //在链表中间节点删除
  11. while(p->next != NULL){
  12. if(p->next->data ==data){//找到节点的下一个为删除位置的目标节点
  13. p->next=p->next->next;//再把目标节点的下一个链接目标节点的后第二个
  14. return head;
  15. }
  16. p=p->next;
  17. }
  18. return head;
  19. }
六、修改非链表头节点内容

实现步骤分为两步:1.1 找到要修改的节点位置

2.1 把节点位置对应的数据修改成新数据

  1. int reviseLink(struct Test *head,int data,int newdata)
  2. {
  3. while(head != NULL){
  4. if(head->data == data){
  5. head->data = newdata
  6. return 1;
  7. }
  8. head = head->next;
  9. }
  10. return 0;
  11. }
七、动态创建链表

1、头插法创建链表

  1. struct Test* creatLink(struct Test *head)
  2. {
  3. struct Test *new;//定义临时结构体指针
  4. while(1){
  5. new=(struct Test*)malloc(sizeof(struct Test));//开辟动态空间内存
  6. printf("input your new node data\n");//提醒用户新插入节点位置
  7. scanf("%d",&(new->data));//输入数据放在临时结构体指针的数据里
  8. if(new->data==0){
  9. printf("0 quit\n");
  10. free(new);
  11. return head;
  12. }//防止插入失败,释放节点
  13. head= insertFromHead(head,new);//
  14. }
  15. }
  1. struct Test* insertFromHead(struct Test *head,struct Test *new)
  2. {
  3. if(head==NULL){
  4. head=new;
  5. }else{
  6. new->next=head;
  7. head=new;
  8. }
  9. return head;
  10. }

2、尾插法创建链表

  1. struct Test* creatLink2(struct Test *head)
  2. {
  3. struct Test *new;
  4. while(1){
  5. new=(struct Test*)malloc(sizeof(struct Test));
  6. printf("input your new node data\n");
  7. scanf("%d",&(new->data));
  8. if(new->data==0){
  9. printf("0 quit\n");
  10. free(new);
  11. return head;
  12. }
  13. head= insertBehind(head,new);
  14. }
  15. }
  1. struct Test* insertBehind(struct Test *head,struct Test *new)
  2. {
  3. struct Test *p=head;
  4. if(p == NULL){
  5. head=new;
  6. return head;
  7. }
  8. while(p->next != NULL){
  9. p=p->next;
  10. }
  11. p->next=new;
  12. return head;
  13. }

3、尾插法

  1. struct ListNode* ReverseList(struct ListNode* pHead ) {
  2. if(pHead == NULL) return NULL;
  3. if(pHead -> next == NULL) return pHead;
  4. struct ListNode* p = NULL;
  5. struct ListNode* tmp = NULL;
  6. p = pHead -> next;
  7. pHead -> next = NULL;
  8. while(p -> next != NULL){
  9. tmp = p -> next;
  10. p -> next = pHead;
  11. pHead = p;
  12. p = tmp;
  13. }
  14. p->next = pHead;
  15. pHead = p;
  16. return pHead;
  17. }
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号