c语言单向链表

Posted 506941763lcj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言单向链表相关的知识,希望对你有一定的参考价值。

一、链表概述  

  链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
        链表的各类操作包括:学习单向链表的创建、删除、  插入(无序、有序)、输出、  排序(选择、插入、冒泡)、反序等等。
二、链表创建、删除、插入等如下,将函数与声明定义进行分离为.h和.c:

2.1 linklist.h

 1 #pragma once
 2 typedef struct list
 3 
 4     int data;//数据域
 5     struct list *next;//指针域
 6 LinkList;
 7 LinkList *crate_list();    //建立一个节点
 8 void traverse(LinkList*ls);//循环遍历链表
 9 LinkList* insert_list(LinkList* ls, int n, int data);//在指定位置插入元素
10 int delete_list(LinkList* ls, int n);//删除指定位置元素
11 int count_list(LinkList* ls);//返回链表元素的个数
12 void clear_list(LinkList *ls);//清空链表,只保留首节点
13 int empty_list(LinkList *ls);//返回链表是否为空
14 LinkList *local_list(LinkList*ls, int n);//返回链表指定的位置节点
15 LinkList * elem_list(LinkList* ls, int data);//返回指定位置data
16 int elem_pos(LinkList *ls, int data);//返回数据域等于DATA的位置
17 LinkList *last_list(LinkList *ls);//得到链表的最后一个节点
18 void merge_list(LinkList * s1,LinkList* s2);//合并两个链表
19 void reverse_lsit(LinkList *ls);//链表反转

2.2  linklist.c

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include "linlist.h"
  4 //建立一个节点
  5 LinkList * crate_list()
  6 
  7     return (LinkList*)calloc(sizeof(LinkList),1);
  8 
  9 //循环遍历链表
 10 void traverse(LinkList * ls)
 11 
 12     LinkList *p = ls;
 13     while (p)
 14     
 15         printf("%d\\n",p->data);
 16         p = p->next;
 17     
 18 
 19 
 20 //插入元素
 21 LinkList * insert_list(LinkList * ls, int n, int data)
 22 
 23     LinkList *p = ls;
 24     while (p&&n--)
 25     
 26         p = p->next;
 27     
 28     if (p==NULL)
 29     
 30         return NULL;//n的位置大于链表节点数
 31     
 32     LinkList *node = crate_list();//新建一个节点
 33     node->data = data;
 34     node->next = p->next;
 35     p->next = node;
 36     return node;
 37 
 38 //删除节点
 39 int delete_list(LinkList * ls, int n)
 40 
 41     LinkList *p = ls;
 42     while (p&&n--)
 43     
 44         p = p->next;
 45     
 46     if (p==NULL)
 47     
 48         return -1;
 49     
 50     LinkList *tmp = p->next;
 51     p->next = p->next->next;
 52     free(tmp);
 53     return 0;
 54 
 55 //返回链表元素的个数
 56 int count_list(LinkList * ls)
 57 
 58     LinkList *p = ls;
 59     int count = 0;
 60     while (p)
 61     
 62         count++;
 63         p = p->next;
 64     
 65     return count;
 66 
 67 //清空链表,只保留首节点
 68 void clear_list(LinkList * ls)
 69 
 70     LinkList* p = ls->next;
 71     while (p)
 72     
 73         LinkList * tmp = p->next;
 74         free(p);
 75         p = tmp;
 76     
 77     ls->next = NULL;//只有首节点,则首节点next实则为NULL
 78 
 79 //返回聊表是否为空
 80 int empty_list(LinkList * ls)
 81 
 82     if (ls->next)
 83         return 0;
 84     else
 85         return -1;
 86     return 0;
 87 
 88 //返回链表指定位置的节点数据域
 89 LinkList * local_list(LinkList * ls, int n)
 90 
 91     LinkList* p = ls;
 92     while (p&&n--)
 93     
 94         p=p->next;
 95     
 96     if (p == NULL)
 97         return NULL;
 98     return p;
 99 
100 //返回指定位置数据域对应的节点
101 LinkList * elem_list(LinkList * ls, int data)
102 
103     LinkList*p = ls;
104     while (p)
105     
106         if (p->data = data)
107             return p;
108         p = p->next;
109     
110     return NULL;//没有找到
111 
112 //返回数据域等于data的节点位置
113 int elem_pos(LinkList * ls, int data)
114 
115     LinkList * p = ls;
116     int index = 0;
117     while (p)
118     
119         index++;
120         if (p->data = data)
121             return index;
122         p = p->next;
123     
124     return -1;//没有找到索引
125 
126 
127 LinkList * last_list(LinkList * ls)
128 
129     LinkList * p = ls;
130     while (p->next)
131     
132         p = p->next;
133     
134     return p;
135 
136 //合并两个链表,将结构放在第一个链表中
137 void merge_list(LinkList * s1, LinkList * s2)
138 
139     //合并连标点节点,不合并链表头
140     last_list(s1)->next = s2->next;
141     free(s2);
142 
143 
144 void reverse_lsit(LinkList * ls)
145 
146     if (ls->next == NULL)
147         return;//只有只有一个头节点
148     if (ls->next->next == NULL)
149         return;
150     LinkList * last = ls->next;//ls->next为最后一个节点
151     LinkList * pre = ls;//上一个节点的指针
152     LinkList *cur = ls->next;//当前节点
153     LinkList*next = NULL;//下一个节指针
154     while (cur)
155     
156         next = cur->next;
157         cur->next = pre;
158         pre = cur;
159         cur = next;
160     
161     ls->next = pre;
162     last->next = NULL;
163 

2.3  测试主函数

 1 #include<stdlib.h>
 2 #include<stdio.h>
 3 #include"linlist.h"
 4 #define Len 10
 5 int main()
 6 
 7     LinkList *first = crate_list();//创建第一个节点
 8     LinkList *second = crate_list();//创建第二个节点
 9     LinkList *third = crate_list();//创建第三个节点
10     first->next = second;//指针域第一个节点的指针指向下一节点
11     second->next = third;//指针域第二个节点的指针指向下一节点
12     third->next = NULL;//指针域第三个节点的指针指向下一节点,只有三个元素,所以下一节点为NULL
13     first->data = 1;//数据域第一个元素
14     second->data = 2;//数据域第二个元素
15     third->data = 3;//数据域第二个元素
16     //遍历链表
17     printf("插入前:\\n");
18     traverse(first);//遍历头即可打印整个链表,因为链表是靠指针连接在一起
19     insert_list(first,0,100);
20     printf("插入后:\\n");
21     traverse(first);
22     printf("删除后\\n");
23     delete_list(first,2);
24     traverse(first);
25     printf("--------------------------------------\\n");
26     printf("链表的个数cout=%d\\n", count_list(first));
27     //printf("清空链表,直保留首节点\\n");
28     //clear_list(first);
29     printf("链表的个数cout=%d\\n", count_list(first));
30     printf("%d\\n",local_list(first,2)->data);
31     printf("data=%d\\n",last_list(first)->data);
32     printf("-----------------------------------------\\n");
33 
34     LinkList * pp = crate_list();
35     for (int i = 0; i < Len; i++)
36     
37         insert_list(pp,0,i);
38     
39     merge_list(first,pp);
40     traverse(first);
41     printf("xxxxxxxxxxxxxxxxxxxx");
42     reverse_lsit(first);
43     traverse(first);
44     return 0;
45 

2.4 结果显示:

技术图片技术图片

以上是关于c语言单向链表的主要内容,如果未能解决你的问题,请参考以下文章

Java 数据结构 & 算法宁可累死自己, 也要卷死别人 7 单向链表

Java 数据结构 & 算法宁可累死自己, 也要卷死别人 7 单向链表

3-1单向链表

队列(链式队列)

05-2_单向链表

LeetCode刷题总结-链表