一.总
目的:记录n个人的年龄。另外要删去年龄重复的结点,从而使得最终n个人的年龄各不相同。
思考点:我在调试的时候,感觉到最困难的部分,是修改“删去重复结点函数”。但这时我使用“数形结合”的思想,来帮助我理解代码,就会很清楚问题出在哪里,最终取得了还不错的效果。
对象:单链表
方法:使用4个自定义函数:创建链表函数、删除结点函数、链表遍历函数、删去重复结点函数。
二.分(全部代码拆成以下的6部分)
1.创建链表函数
void Create(note* head,int n)
{
for (int i = 1; i <= n; i++) {
note* p;
p = (note*)malloc(sizeof(note));
if (p) {
fgets(p->age, 20, stdin);
p->next = head->next;
head->next = p;
}
}
}
2.删除结点函数
void Delete(note* head, int n) {
note* x;
x = head;
int i = 0;
while (i < n - 1) {
i++;
x = x->next;
}
note* y;
y = x->next;
x->next = y->next;
free(y);
}
3.链表遍历函数
void Output(note* head)
{
note* p;
p = head->next;
while (p) {
puts(p->age);
p = p->next;
}
}
4.删去重复结点函数
void Func(note* head,int n)
{
note* p;
note* q;
p = (note*)malloc(sizeof(note));
q = (note*)malloc(sizeof(note));
p = head->next->next;
if (p&&q) {
while(p) {
q = head->next;
for (int j = 1 ; (p-q!=0)&&(p->next!=0); j++) {
if (atoi(p->age) == atoi(q->age)) {
q = q->next;
Delete(head, j);
}
}
p = p->next;
}
}
}
5.结构体
typedef struct tapNOTE {
char age[20];
struct tapNOTE* next;
}note;
6.主函数
int main()
{
note* head;
head = (note*)malloc(sizeof(note));
head->next = '\0';
char s[5];
int n;
fgets(s, 5, stdin);
n = atoi(s);
if (head) {
Create(head, n);
}
Func(head, n);
Output(head);
free(head);
return 0;
}
三.数形结合(核心是删去重复结点函数)
首先,输入3个年龄,分别是23,12,12。下图是从键盘输入的内容。
接着,程序从最初开始调试,仅执行创建链表函数后,停在了删去重复结点函数处。下图是auto型变量(非静态局部变量)的内容。
下面是“数形结合”中的“图形”:
分析:
问:现在p和q所指的内存单元中,出现了有重复内容的结点,我们该怎么办呢?
答:我没有学会双链表,只好用笨方法。这个时候,我们使用基础的删除结点函数,来帮助我们删除内容。
1.第1步:更改p的指向,让它指向下一个结点。这时j的值为1,代表着需要删除的结点是第1个。图形如下:
2.第2步:使用删除结点函数,删除第2个结点。
最后,我们不借助双链表,只用单链表和节点删除函数,达到了任务要求。
四.总结
虽然以上的分享,只是优秀程序员们调试的基本功,但是我想传达2个观点:
1.我一直在向我们学校的优秀同学学习,学习他们跨学科的思想,并尝试把高中数学常用的“数形结合”思想应用到编程中。我切身体会到,这样做给我带来了很多欢乐。
2.我也没有忘记高中班主任对我说过的话:“都这个关头了,你们一定要戒骄戒躁,不要眼高手低,多在纸上写写画画。你看我带的生物,为什么就比其他班好?”。戒骄戒躁,勤于动手,是我至今受用不尽的原则。