赞
踩
- #include <stdio.h>
- #include <malloc.h> /用malloc函数获取空间。
- struct Node /*定义链表结点的类型*/
- {
- int data; /*数据域*/
- struct Node* next; /*指针域*/
- };
- typedef struct Node Node; /*重命名,定义类型的别名为Node,方便使用*/
-
- Node* Create(); /* 创建一个新的链表 */
- void Print(Node* head); /* 打印链表 */
- void Release(Node* head); /* 释放链表所占的内存空间 */
- Node* Delete(Node* head, int num);//删去
- int main()
- {
- Node* head; /* 定义头指针head */
- int num;
- head = Create(); /* 创建一个新的链表,返回的头指针赋值给head */
- Print(head); /* 链表的遍历输出每个元素的值 */
- printf("请输入要删除的数 :\n");
- scanf("%d", &num);
- head = Delete(head, num); //返回指针类型
- printf("删除%d之后的单链表:\n", num);
- Print(head); //传入指针
- Release(head); /*释放链表每个结点的存储空间*/
- return 0;
- }
-
- /* 函数功能: 创建一个单链表
- 函数入口参数:无
- 函数返回值: 链表的头指针
- */
- Node* Create()
- {
- Node* head, * tail, * p; /* head、tail分别指向链表的头结点和尾结点 */
- int num; //局部变量
- head = tail = NULL; /* 链表初始化: 空链表 */
- printf("请输入一批数据,以-9999结尾: \n");
- scanf("%d", &num);//此处是处理第一个数据外,存储在缓存区。
- while (num != -9999) /* 用户数据输入未结束 */
- {
- p = (Node*)malloc(sizeof(Node)); /* 申请一块节点的内存用于存放数据 */
- p->data = num; /* 将数据存于新结点的data成员中 */
- p->next = NULL; /* 新结点的指针域及时赋为空值 */
- if (NULL == head) /* 如果原来链表为空 */
- {
- head = p; /* 则将p赋值给head,p是刚申请的第一个结点 */
- }
- else /* 如果原来链表非空 */
- {
- tail->next = p; /* 则将新结点链入尾部成为新的最后一个结点 */
- }
- tail = p; /* 更新tail指针,让其指向新的尾结点处 */
- scanf("%d", &num); /* 继续读入数据 */
- }
- return head; /* 返回链表的头指针 */
- }
- /* 函数功能: 遍历单链表输出每个结点中的元素值
- 函数入口参数:链表的头指针
- 函数返回值: 无
- */
- void Print(Node* head)
- {
- Node* p; /* 定义工作指针p */
- p = head; /* p从头指针开始 */
- if (NULL == head) /* 如果链表为空输出提示信息 */
- {
- printf("链表为空!\n");
- }
- else是否会有疑问,为什么不是p.data因为不是普通变量,是指针。
- {
- printf("链表如下\n");
- while (p != NULL) /*用 p来控制循环,p为空指针时停止*/
- {
- printf("%d ", p->data); /*输出 p当前指向的结点的元素值*/
- p = p->next; /* p指向链表的下一个结点处*/
- }
- }
- printf("\n");
- }
- /* 函数功能: 释放单链表中所有的动态结点
- 函数入口参数:链表的头指针
- 函数返回值: 无
- */
- void Release(Node* head) /* 仍然是使用遍历的方法扫描每一个结点*/
- {
- Node* p1, * p2; /* p1用来控制循环,p2指向当前删除结点处*/
- p1 = head;
- while (p1 != NULL)
- {
- p2 = p1; /*p2指向当前删除结点处*/
- p1 = p1->next; /* p1指向链表下一个结点位置处*/
- free(p2); /* 然后通过p2释放动态空间*/
- }
- printf("链表释放内存成功!\n");
- }
-
- /* 函数功能: 从单链表中删除指定的元素,返回新链的头指针
- 函数入口参数:2个形式参数依次为链表的头指针、待删除的元素值
- 函数返回值: 链表的头指针
- */
- Node* Delete(Node* head, int num) /* num为待删除数据,删除节点 */
- {
- Node* p1, * p2;
- if (NULL == head) /* 空链表判断 */
- {
- printf("链表为空!\n");//
- return head; //链表本来就是空的,就不用删除了。
- }
- p1 = head; /* p1用于查找待删除结点,从head指针开始*/
- while (p1->next && p1->data != num) //p->next指向下一个为0或者等于要找到数时num时。循环停止
- /*在链表中寻找指定数据,若不相等则循环 */
- {//找到要断的链子在那,才能断。
- p2 = p1; /* 用p2记下原来p1的位置 *///保持两个指针距离相邻。
- p1 = p1->next; /* p1指针向后移动 */
- }
- if (p1->data == num) /*p1指向当前节点的data,找到该数据 */
- {
- if (head == p1) /* 如果删除的是第一个结点 */
- {
- head = p1->next; /* 则修改头指针 ,将头节点往后移动,因为p1->next存放的是下一个的地址,dead也是指针型的*/
- }
- else /* 如果不是第一个结点 */
- {
- p2->next = p1->next; //等价于p1的下一个节点的地址赋值给刚刚在p1屁股后面的p2,而p1本身还是指向要删除的数据域,
- /* 则执行此操作将p1从链中脱开*/
- }
- free(p1); /* 释放p1结点的内存空间 ,仅仅是销毁了指针指向的空间,但指针还在。*/
- printf("删除成功!\n");
- }
- else /*循环终止时 p1->data != num 没找到 */
- {
- printf("链表中无此数据!\n");
- }
- return head;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。