PTA 链表删除结点的题目测试
2016-03-31 17:53
537 查看
链表删除结点
题目描述
输入一个正整数repeat(0
输入格式
见输入样例
输出格式
见输出样例
输入样例
3 5 1 2 4 3 7 4 5 2 1 5 7 5 5 3 1 2 4 100
输出样例
size=4:1 2 3 7 size=4:2 1 5 7 size=3:1 2 4
思路
创建一条单向链表,因为题目要找出并删除最后一个与x相同的数,所以反转链表,删除第一个与x相同的数,这样就不用做标记,删除后再反转一次,最后输出。#include<stdio.h> #include<stdlib.h> int flag; struct Node{ int num; struct Node *next; }; struct Node *Create(int n) //创建链表 { struct Node *current,*prev; struct Node *head = NULL; int cnt = 0; while (cnt != n) { current = (struct Node *)malloc(sizeof(struct Node)); scanf("%d",¤t->num); if (head == NULL) head = current; else prev->next = current; prev = current; cnt++; } prev->next = NULL; return head; } void Print(struct Node *head) //打印链表 { struct Node * current; current = head; printf("%d",current->num); current = current->next; while (current != NULL) { printf(" %d",current->num); current = current->next; } printf("\n"); } struct Node *Reverse(struct Node *head) //反转链表 { struct Node *current,*prev,*tmp; current = head; prev= current->next; while (prev != NULL) { tmp = prev->next; prev->next = current; current = prev; prev = tmp; } head->next = NULL; head = current; return head; } struct Node *Delete(struct Node *head,int num) //删除特定结点 { struct Node *current; struct Node *prev; current = head; while (current->num != num && current->next != NULL) { prev = current; current = current->next; } if (current->num == num) { if (head == current) { head = current->next; } else { prev->next = current->next; } } else { flag = 0; } return head; } int main() { int N,repeat,x; struct Node *head; scanf("%d",&repeat); while (repeat--) { flag = 1; scanf("%d",&N); head = Create(N); scanf("%d",&x); head = Reverse(head); head = Delete(head,x); head = Reverse(head); if (flag) printf("size=%d:",N-1); else printf("size=%d:",N); Print(head); } return 0; }
后来在和同学讨论的时候发现自己忘了释放内存,之后就补了Free函数
void Free(struct Node *head) { struct Node *current; current = head; while (current != NULL) { free(current); current = current->next; } }
但是在添加Free函数调用它的时候主函数中只repeat了一次,没有再次进入while(repeat–)中,回看代码看了很久都没发现错误,除Free函数各模块代码都没有错,因为之前没有Free函数时都可以正常的输出。之后调试了一下程序,发现程序一直停止在
Free(head);
这个语句。问了下学姐,提醒我打出current地址,尝试打印了一下Free函数里面current变量的地址值
地址五个一次循环,难怪一直没有第二次进入while循环。但是在Free函数里面也没发现错误。最后求助了学长,学长说在Free函数里面,free掉current后又用到了current的值导致出错。然后我就尝试着修改了一下
while (current != NULL) { tmp = current; free(current); current = tmp->next; }
运行之后还是老样子,想了很久没发现逻辑上的问题,学长学姐提点了一下,tmp和current指向同一个内存区,然后又free掉了,所以tmp最后也指向了不明内存区,跟第一次犯的错误根源上一样。现在也慢慢发现对于指针的内涵还是不是很懂。最后改成如此
void Free(struct Node *head) { struct Node *current,*tmp; current = head; while (current != NULL) { tmp = current->next; free(current); current = tmp; } }
附上某大神本题另一种解法:
#include <cstdio> using namespace std; struct Node{ int val; Node *next; } tab[10086]; Node *p[10086]; int n,repeat; int i,j,k,x; int main() { scanf("%d",&repeat); for(j=0; j<repeat; j++) { scanf("%d",&n); for (i=0; i<=20; i++) p[i]=&tab[i]; //--1 read for (i=1; i<=n; i++) { scanf("%d",&p[i]->val); p[i-1]->next=p[i]; } p ->next=NULL; //--2 search x scanf("%d",&x); Node *tmp=NULL; for (Node *tai=p[0]->next; tai!=NULL; tai=tai->next) if (tai->val==x) tmp=tai; //--3 delete tmp for (Node *tai=p[0]; tai!=NULL; tai=tai->next) if (tai->next!=NULL) if (tai->next==tmp) { tai->next=tai->next->next; n-=1; } //--4 Print printf("size=%d:",n); for (Node *tai=p[0]->next; tai!=NULL; tai=tai->next) { printf("%d",tai->val); n-=1; if(n>0) printf(" "); } if (j<repeat-1) printf("\n"); } return 0; }
总结
虽然在线提交的时候,数据点测试通过,但是没有考虑指针,通过简单的一个Free函数,折腾了好久,也错了很多次,但也因此更了解指针指针的理解与应用仍需加强啊
相关文章推荐
- HDU 1087 Super Jumping! Jumping! Jumping!(最大的上升子序列的和)(不是最长)(易混淆)
- 错误expression: invalid operator<
- 关于platform_driver 是如何匹配 platform_device的和如何调用到platform_driver中的probe函数的研究
- 编辑器笔记——sublime text3 编译sass
- win32收不到F10按键消息解决办法
- 构建执法阅读笔记4
- bootstrap表单带验证
- linux下搭建一个xampp环境进行性能测试
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Linux: apt-get vs aptitude and 'ldconfig' problem solving (libc-bin package)
- Android图片压缩(质量压缩和尺寸压缩)
- AOP实现原理——动态代理
- Android性能优化
- C#中数据库中image类型可转为byte[]类型
- 总线设备驱动模型----驱动篇