编译结果;
1root@ubuntu-virtual-machine:/mnt/hgfs/day# gcc flie1.c
2root@ubuntu-virtual-machine:/mnt/hgfs/day# ./a.out
3beader node data: 3.
4----------开始遍历-----------
5node data: 13.
6node data: 12.
7node data: 11.
8 -------------完了-------------
二、单链表的删除
1、如何找到要删除的节点?
通过遍历来查找节点。从头指针+头节点开始,顺着链表依次将各个节点拿出来,按照一定的方法比对,找到我们要删除的那个节点。
2、如何来删除一个节点?
(1)待删除的节点不是尾节点的情况:首先把待删除的节点的前一个节点的pNext指针指向待删除的节点的后一个节点的首地址(这样就把这个节点从链表中摘出来了),然后再将这个摘出来的节点free掉接口。
(2)待删除的节点是尾节点的情况:首先把待删除的尾节点的前一个节点的pNext指针指向null(这时候就相当于原来尾节点前面的一个节点变成了新的尾节点),然后将摘出来的节点free掉。
3、实战代码演示:
1 #include <stdio.h>
2 #include <strings.h>
3 #include <stdlib.h>
4// 构建一个链表的节点
5struct node
6 {
7 int data; // 有效数据
8 struct node *pNext;
9 // 指向下一个节点的指针
10 };
11 // 作用:创建一个链表节点
12 // 返回值:指针,指针指向我们本函数新创建的一个节点的首地址
13 struct node * create_node(int data)
14 {
15 struct node *p = (struct node *)malloc(sizeof(struct node));
16 if (NULL == p)
17 {
18 printf("malloc error.n");
19 return NULL;
20 }
21 // 清理申请到的堆内存
22 bzero(p, sizeof(struct node));
23 // 填充节点
24 p->data = data;
25 p->pNext = NULL;
26 return p;
27}
28// 计算添加了新的节点后总共有多少个节点,然后把这个数写进头节点中。
29void insert_tail(struct node *pH, struct node *new)
30{
31 int cnt = 0;
32 // 分两步来完成插入
33 // 第一步,先找到链表中最后一个节点
34 struct node *p = pH;
35 while (NULL != p->pNext)
36 {
37 p = p->pNext; // 往后走一个节点
38 cnt++;
39 }
40 // 第二步,将新节点插入到最后一个节点尾部
41 p->pNext = new;
42 pH->data = cnt + 1;
43 }
44 void insert_head(struct node *pH, struct node *new)
45 {
46 // 第1步: 新节点的next指向原来的第一个节点
47 new->pNext = pH->pNext;
48 // 第2步: 头节点的next指向新节点的地址
49 pH->pNext = new;
50 // 第3步: 头节点中的计数要加1
51 pH->data += 1;
52 }
53 // 遍历单链表,pH为指向单链表的头指针,遍历的节点数据打印出来
54 void bianli(struct node*pH)
55 {
56 //pH->data // 头节点数据,不是链表的常规数据,不要算进去了
57 //struct node *p = pH; // 错误,因为头指针后面是头节点
58 struct node *p = pH->pNext; // p直接走到第一个节点
59 printf("-----------开始遍历-----------n");
60 // 是不是最后一个节点
61 while (NULL != p->pNext)
62 {
63 printf("node data: %d.n", p->data);
64 p = p->pNext;
65 // 走到下一个节点,也就是循环增量
66 }
67 printf("node data: %d.n", p->data);
68 printf("-------------完了-------------n");
69 }
70 // 从链表pH中删除节点,待删除的节点的特征是数据区等于data
71 // 返回值:当找到并且成功删除了节点则返回0,当未找到节点时返回-1
72 int delete_node(struct node*pH, int data)
73 {
74// 找到这个待删除的节点,通过遍历链表来查找
75struct node *p = pH; // 用来指向当前节点
76struct node *pPrev = NULL;// 用来指向当前节点的前一个点
77while (NULL != p->pNext)// 是不是最后一个节点
78{
79 pPrev = p; // 在p走向下一个节点前先将其保存
80 p = p->pNext; // 走到下一个节点,也就是循环增量
81 // 判断这个节点是不是我们要找的那个节点
82 if (p->data == data)
83 {
84 // 找到了节点,处理这个节点
85 // 分为2种情况,一个是找到的是普通节点,另一个是找到的是尾节点
86 // 删除节点的困难点在于:通过链表的遍历依次访问各个节点,找到这个节点
87 // 后p指向了这个节点,但是要删除这个节点关键要操作前一个节点,但是这
88 // 时候已经没有指针指向前一个节点了,所以没法操作。解决方案就是增加
89 // 一个指针指向当前节点的前一个节点
90 if (NULL == p->pNext)
91 {
92 // 尾节点
93 pPrev->pNext = NULL; // 原来尾节点的前一个节点变成新尾节点
94 free(p); // 释放原来的尾节点的内存
95 }
96 else
97 {
98 // 普通节点
99 pPrev->pNext = p->pNext;