1、关于尾插法的pTail=pNew的疑惑点

今天学习到了尾插法,但是遇到了一个让我绞尽脑汁都没想明白的点,后面跟室友讨论了一下,才感觉到思想逐渐清晰。先看下面一段代码:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct Node	
{
	int data;	//数据域
	struct Node *next;	//指针域 
} NODE,*PNODE;

PNODE create_list(void);
void traverse_list(PNODE pHead);


int main(void)
{
	PNODE pHead=NULL;	//
	pHead=create_list();		//创建一个肺循环单链表,并将改链表的头结点的地址赋值给pHead 
	traverse_list(pHead);
	
	return 0; 
 }
 
PNODE create_list(void)
{
	int len;	//用来存放有效结点的个数 
	int i;
	int val;	//用来临时存放用户输入的结点的值 
	
	PNODE pHead=(PNODE)malloc(sizeof(NODE));	//此处地方的PHead与下面的PHead无关系,这里的是一个局部变量 
	if(pHead==NULL)
	{
		printf("分配失败,程序终止!\n");
		exit(-1);
	 } 

	PNODE pTail=pHead; pTail->next=NULL;	

	printf("请输入你需要生成链表结点的个数:len=");
	scanf("%d",&len);
	for(i=0;i<len;i++)
	{
		printf("请输入%d个结点的值:",i+1);
		scanf("%d",&val);
		
		//需要一个接受专门接受数据的新节点
		PNODE pNew=(PNODE)malloc(sizeof(NODE));	
		if(NULL==pNew)
		{
			printf("分配失败,程序终止!\n");
			exit(-1);
	 	} 
		pNew->data =val; 
		pTail->next=pNew;
		pNew->next=NULL;
		pTail=pNew;		//这里如何理解? 
		
	} 
	
	
	return pHead;
}
void traverse_list(PNODE pHead)
{
	.....
}

如代码注释所示,在pTail=pNew这里,我产生了一个疑惑点,为什么会这里将pNew赋值给pTail后,pTail又成为了此链表的尾结点了呢?其实一开始我就没有弄清楚pTail的定义是怎样的,一开始定义了一个指针,这个指针永远指向最后一个结点,这个指针就是pTail。为什么一开始我会疑惑呢,回到上面标蓝的字体上,会发现我的逻辑与思维的错误,因为一开始我就把pTail看成了是一个尾结点,以至于前面学习的指针与现在的尾插法发生了严重的冲突,这个地方整整纠结了我一下午,到了第二天才恍然大悟,pTail并不是尾结点,它只是一个指向尾结点的指针变量而已,这就解释了为什么一开始pTail=pHead; pTail->next=NULL;链表一开始为空,pHead->next也指向NULL,此时的头结点我们可以把它看成是一个尾结点,由于我们定义了pTail指向尾结点,于是此处pTail指向了pHead。接着解释为什么对pTail=pNew产生了疑惑,一开始我认为pNew是一个指针,将pNew的地址赋值给pTail后,pTail就指向pNew,但是为什么pTail就又变成了尾结点了呢?其实这里是指,pTail指向的结点变成了尾结点,也就是新插入的那个结点,变成了尾结点,然后pTail再去指向它。pTail还是pTail,它不是结点,它只是一个指针,将pNew的地址赋值给pTail后,pTail就指向了pNew。总结一句话就是,保证每新插一个结点,这个结点就变成尾结点。书上抠了一幅图来了:

自学最大的困难莫过于此,遇到了思维的分叉点,一旦走入了错误的一方,纠正过来需要花费巨大的精力与时间。这个小小的错误,我从开始理解错误到结束理解正确,中间的我甚至还用以前的知识去证明我错误的点是正确的,所以脑子里一直会有一种不和谐感,再次学习的时候还是会纠结会去想,最后乱成一锅粥。但是豁然开朗的感觉又是如此的舒畅,这或许就是学习的乐趣吧!

 

#include <stdio.h> #include <stdlib.h> struct link { int data; struct link *next; }; struct link *AppendNode(struct link *head,int data); void DisplyNode(struct link *head); void DeleteMemory(struct link *head); struct link * DeleteNode(struct link *head,int data); struct link *InsertNode(struct link *head, int nodeData); int main() { char c; int data = 0; struct link head = NULL; / 链表头指针 / while (1) { scanf("%d",&data); if (data==-1) break; head = AppendNode(head,data);/ 向head为头指针的链表末尾添加节 / } DisplyNode(head); / 显示当前链表中的各节信息 / scanf("%d",&data); head = InsertNode(head,data); DisplyNode(head); / 显示当前链表中的各节信息 / DeleteMemory(head); / 释放所有动态分配的内存 */ return 0; } struct link *AppendNode(struct link *head,int data){ struct link pnew,ptail; pnew=head; if(head==NULL){ head=(struct link)malloc(sizeof(struct link)); head->data=data; head->next=NULL; }else{ while(pnew!=NULL){ ptail=pnew; pnew=pnew->next; } pnew=(struct link)malloc(sizeof(struct link)); pnew->data=data; ptail->next=pnew; pnew->next=NULL; } return head; }; void DisplyNode(struct link *head){ struct link *p; p=head; while(p!=NULL){ if(p->next !=NULL) printf("%d->",p->data); else{ printf("%d\n",p->data); break; } p=p->next; } } struct link *InsertNode(struct link *head, int nodeData){ struct link *p,q,t; p=head; if(head->data>nodeData){ head=(struct link)malloc(sizeof(struct link)); head->data=nodeData; head->next=p; }else{ while(1){ if(p->next->data>nodeData) { q=(struct link)malloc(sizeof(struct link)); t=p->next; p->next=q; q->data=nodeData; q->next=t; break; } p=p->next; } } return head; }; void DeleteMemory(struct link *head) { free (head); }
06-11
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值