user-0 提问: 链表头结点

回复:
user: user-0
content: 引用 9 楼 lm_whales 的回复:链表有带头结点，和不带的 带头节点的，首节点就是头结点，可以存放长度，等信息，充分利用空间。 也可以不存放数据。 第二个节点才是第一个数据节点 不带头结点的链表，首节点就是第一个数据节点，每个节点都储存数据。  带头节点的链表，比不带的， 处理更方便，更统一。 但是多用一个节点。  恩，现在清楚啦，谢谢你啊~~

user: user-0
content: 引用 7 楼 user-3 的回复:[quote=引用 6 楼 a904235765 的回复:] [quote=引用 4 楼 user-3 的回复:] 链表的头结点该不该存放数据，或者存放什么数据，是灵活的，没有标准，可以根据实际需要来设计。 从你的程序来看，应该是想创建一个链表，链表的长度由用户指定，链表头结点存放链表长度，同时head也指向头结点，并且打印每个结点地址。如果是这样，那程序需要改进： 1. 不需要传入参数head，head直接返回就可以了，如果想通过参数把head返回给caller，则需要定义双重指针，否则无效。 2. while循环体内的scanf("%d",&p1->num)多余的，链表的长度不可能每次创建一个结点都重置。 3. 循环体外的打印也是多余的。 修改程序如下： #include <stdio.h> #include <stdlib.h>  typedef struct node { 	int num; 	node *next; }node;  struct node *creat() { 	struct node *p1 = NULL, *p2 = NULL; 	struct node *head = NULL; 	p1 = p2 = (struct node *)malloc(sizeof(struct node)); 	printf("0: %x\n", p1); 	printf("please enter list's length: "); 	scanf("%d", &p1->num); 	p1->next = NULL; 	int n = p1->num; 	int i = 0; 	while(n--) 	{ 		if(head == NULL) 		{ 			head = p1; 		} 		else 			p2->next = p1; 		p2 = p1; 		p1 = (struct node *)malloc(sizeof(struct node)); 		printf("%d: %x\n", ++i, p1); 		//scanf("%d",&p1->num); 	} 	//printf("p2->next=%d\n", p2->next); 	return head; }  int main() { 	node *n = creat(); 	return 0; }  第一个结点编号是0， 之后每个结点编号从1开始。函数返回head。 return head前要添加一句p2->next=NULL？ [/quote]  抱歉，刚才的程序有bug，首结点没有和后面的结点相连。我重新改了一下代码，简化了一下，把所有打印语句放在函数外面，算是调试。程序能运行。  #include <stdio.h> #include <stdlib.h>  typedef struct node { 	int num; 	node *next; }node;  struct node *creat() { 	struct node *p1 = NULL, *p2 = NULL; 	struct node *head = NULL; 	head = p1 = p2 = (struct node *)malloc(sizeof(struct node)); 	//printf("0: %x\n", p1); 	//printf("please enter list's length: "); 	scanf("%d", &p1->num); 	p1->next = NULL; 	int n = p1->num; 	int i = 0; 	while(n--) 	{ 		/* 		if(head == NULL) 		{ 			head = p1; 		} 		else 			p2->next = p1;*/ 		//p2 = p1; 		p1 = (struct node *)malloc(sizeof(struct node)); 		p1->next = NULL; 		p2->next = p1; 		p2 = p1; 		//printf("%d: %x\n", ++i, p1); 		//scanf("%d",&p1->num); 	} 	//printf("p2->next=%d\n", p2->next); 	return head; }  int main() { 	node *p = creat(); 	int n = 0; 	printf("number of node/address of node/address of next node\n"); 	while(p) 	{ 		printf("     %d            0x%x           %x\n", n++, p, p->next); 		p = p->next; 	} 	return 0; }[/quote] 恩，明白了，谢谢你啊  那么耐心~~

user: user-1
content: 链表有带头结点，和不带的 带头节点的，首节点就是头结点，可以存放长度，等信息，充分利用空间。 也可以不存放数据。 第二个节点才是第一个数据节点 不带头结点的链表，首节点就是第一个数据节点，每个节点都储存数据。  带头节点的链表，比不带的， 处理更方便，更统一。 但是多用一个节点。

user: user-0
content: 引用 1 楼 lansong4 的回复:看需求是怎样的， 如果程序经常要用到线性表的长度，那么头节点可开个空间存储线性表的长度， 不过在线性表的 添加 和 删除 也要对头节点的长度进行相应的操作。  struct ListNode { ListNode* pNext; int nData; };  struct ListHead {    ListNode* pHead;    int nListLen; }； 那就是说在不需要统计链表的长度时，头结点可以不放数据？ 还有再麻烦你看看这段创建链表的代码： //创建链表 struct node *creat(struct node *head) {     struct node *p1,*p2; 	p1=p2=(struct node *)malloc(sizeof(struct node)); 	printf("%d",p1); 	scanf("%d",&p1->num); 	p1->next=NULL; 	while(p1->num>0) 	{       if(head==NULL) 	  { 	   head=p1; 	  } 	  else 		p2->next=p1;          p2=p1; 	  p1=(struct node *)malloc(sizeof(struct node)); 	  printf("p2=%d",p2); 	  scanf("%d",&p1->num); 	} 	printf("p2->next=%d",p2->next); 	return head; }  	printf("p2->next=%d",p2->next);这一句的输出结果为0，可是在程序中并没有这样的语句啊？输出怎么会是0？

user: user-2
content: 看需求是怎样的， 如果程序经常要用到线性表的长度，那么头节点可开个空间存储线性表的长度， 不过在线性表的 添加 和 删除 也要对头节点的长度进行相应的操作。  struct ListNode { ListNode* pNext; int nData; };  struct ListHead {    ListNode* pHead;    int nListLen; }；

user: user-3
content: //printf("please enter list's length: ");  注释去掉。

user: user-3
content: 引用 6 楼 a904235765 的回复:[quote=引用 4 楼 user-3 的回复:] 链表的头结点该不该存放数据，或者存放什么数据，是灵活的，没有标准，可以根据实际需要来设计。 从你的程序来看，应该是想创建一个链表，链表的长度由用户指定，链表头结点存放链表长度，同时head也指向头结点，并且打印每个结点地址。如果是这样，那程序需要改进： 1. 不需要传入参数head，head直接返回就可以了，如果想通过参数把head返回给caller，则需要定义双重指针，否则无效。 2. while循环体内的scanf("%d",&p1->num)多余的，链表的长度不可能每次创建一个结点都重置。 3. 循环体外的打印也是多余的。 修改程序如下： #include <stdio.h> #include <stdlib.h>  typedef struct node { 	int num; 	node *next; }node;  struct node *creat() { 	struct node *p1 = NULL, *p2 = NULL; 	struct node *head = NULL; 	p1 = p2 = (struct node *)malloc(sizeof(struct node)); 	printf("0: %x\n", p1); 	printf("please enter list's length: "); 	scanf("%d", &p1->num); 	p1->next = NULL; 	int n = p1->num; 	int i = 0; 	while(n--) 	{ 		if(head == NULL) 		{ 			head = p1; 		} 		else 			p2->next = p1; 		p2 = p1; 		p1 = (struct node *)malloc(sizeof(struct node)); 		printf("%d: %x\n", ++i, p1); 		//scanf("%d",&p1->num); 	} 	//printf("p2->next=%d\n", p2->next); 	return head; }  int main() { 	node *n = creat(); 	return 0; }  第一个结点编号是0， 之后每个结点编号从1开始。函数返回head。 return head前要添加一句p2->next=NULL？ [/quote]  抱歉，刚才的程序有bug，首结点没有和后面的结点相连。我重新改了一下代码，简化了一下，把所有打印语句放在函数外面，算是调试。程序能运行。  #include <stdio.h> #include <stdlib.h>  typedef struct node { 	int num; 	node *next; }node;  struct node *creat() { 	struct node *p1 = NULL, *p2 = NULL; 	struct node *head = NULL; 	head = p1 = p2 = (struct node *)malloc(sizeof(struct node)); 	//printf("0: %x\n", p1); 	//printf("please enter list's length: "); 	scanf("%d", &p1->num); 	p1->next = NULL; 	int n = p1->num; 	int i = 0; 	while(n--) 	{ 		/* 		if(head == NULL) 		{ 			head = p1; 		} 		else 			p2->next = p1;*/ 		//p2 = p1; 		p1 = (struct node *)malloc(sizeof(struct node)); 		p1->next = NULL; 		p2->next = p1; 		p2 = p1; 		//printf("%d: %x\n", ++i, p1); 		//scanf("%d",&p1->num); 	} 	//printf("p2->next=%d\n", p2->next); 	return head; }  int main() { 	node *p = creat(); 	int n = 0; 	printf("number of node/address of node/address of next node\n"); 	while(p) 	{ 		printf("     %d            0x%x           %x\n", n++, p, p->next); 		p = p->next; 	} 	return 0; }

user: user-0
content: 引用 4 楼 user-3 的回复:链表的头结点该不该存放数据，或者存放什么数据，是灵活的，没有标准，可以根据实际需要来设计。 从你的程序来看，应该是想创建一个链表，链表的长度由用户指定，链表头结点存放链表长度，同时head也指向头结点，并且打印每个结点地址。如果是这样，那程序需要改进： 1. 不需要传入参数head，head直接返回就可以了，如果想通过参数把head返回给caller，则需要定义双重指针，否则无效。 2. while循环体内的scanf("%d",&p1->num)多余的，链表的长度不可能每次创建一个结点都重置。 3. 循环体外的打印也是多余的。 修改程序如下： #include <stdio.h> #include <stdlib.h>  typedef struct node { 	int num; 	node *next; }node;  struct node *creat() { 	struct node *p1 = NULL, *p2 = NULL; 	struct node *head = NULL; 	p1 = p2 = (struct node *)malloc(sizeof(struct node)); 	printf("0: %x\n", p1); 	printf("please enter list's length: "); 	scanf("%d", &p1->num); 	p1->next = NULL; 	int n = p1->num; 	int i = 0; 	while(n--) 	{ 		if(head == NULL) 		{ 			head = p1; 		} 		else 			p2->next = p1; 		p2 = p1; 		p1 = (struct node *)malloc(sizeof(struct node)); 		printf("%d: %x\n", ++i, p1); 		//scanf("%d",&p1->num); 	} 	//printf("p2->next=%d\n", p2->next); 	return head; }  int main() { 	node *n = creat(); 	return 0; }  第一个结点编号是0， 之后每个结点编号从1开始。函数返回head。 return head前要添加一句p2->next=NULL？

user: user-0
content: 引用 3 楼 lansong4 的回复:[quote=引用 2 楼 a904235765 的回复:] [quote=引用 1 楼 lansong4 的回复:] 看需求是怎样的， 如果程序经常要用到线性表的长度，那么头节点可开个空间存储线性表的长度， 不过在线性表的 添加 和 删除 也要对头节点的长度进行相应的操作。  struct ListNode { ListNode* pNext; int nData; };  struct ListHead {    ListNode* pHead;    int nListLen; }； 那就是说在不需要统计链表的长度时，头结点可以不放数据？ 还有再麻烦你看看这段创建链表的代码： //创建链表 struct node *creat(struct node *head) {     struct node *p1,*p2; 	p1=p2=(struct node *)malloc(sizeof(struct node)); 	printf("%d",p1); 	scanf("%d",&p1->num); 	p1->next=NULL; 	while(p1->num>0) 	{       if(head==NULL) 	  { 	   head=p1; 	  } 	  else 		p2->next=p1;          p2=p1; 	  p1=(struct node *)malloc(sizeof(struct node)); 	  printf("p2=%d",p2); 	  scanf("%d",&p1->num); 	} 	printf("p2->next=%d",p2->next); 	return head; }  	printf("p2->next=%d",p2->next);这一句的输出结果为0，可是在程序中并没有这样的语句啊？输出怎么会是0？  [/quote] 看需求才觉得是否在头里加数据域。 你这段代码本身就有问题，应该是这样的，NULL的整数值就是0，所以输出是0：  struct node *creat(struct node *head) {     struct node *p1,*p2; 	p1=p2=(struct node *)malloc(sizeof(struct node)); 	printf("%d",p1); 	scanf("%d",&p1->num); 	p1->next=NULL; 	while(p1->num>0) 	{       if(head==NULL) 	  { 	   head=p1; 	  } 	  else 		p2->next=p1;          p2=p1;          p2->next=NULL;//加多这句 	  p1=(struct node *)malloc(sizeof(struct node)); 	  printf("p2=%d",p2); 	  scanf("%d",&p1->num); 	} 	printf("p2->next=%d",p2->next); 	return head; }  	printf("p2->next=%d",p2->next);[/quote] 恩，是要添加这一句的，现在明白了，谢谢你这么耐心的解答~~谢谢

user: user-3
content: 链表的头结点该不该存放数据，或者存放什么数据，是灵活的，没有标准，可以根据实际需要来设计。 从你的程序来看，应该是想创建一个链表，链表的长度由用户指定，链表头结点存放链表长度，同时head也指向头结点，并且打印每个结点地址。如果是这样，那程序需要改进： 1. 不需要传入参数head，head直接返回就可以了，如果想通过参数把head返回给caller，则需要定义双重指针，否则无效。 2. while循环体内的scanf("%d",&p1->num)多余的，链表的长度不可能每次创建一个结点都重置。 3. 循环体外的打印也是多余的。 修改程序如下： #include <stdio.h> #include <stdlib.h>  typedef struct node { 	int num; 	node *next; }node;  struct node *creat() { 	struct node *p1 = NULL, *p2 = NULL; 	struct node *head = NULL; 	p1 = p2 = (struct node *)malloc(sizeof(struct node)); 	printf("0: %x\n", p1); 	printf("please enter list's length: "); 	scanf("%d", &p1->num); 	p1->next = NULL; 	int n = p1->num; 	int i = 0; 	while(n--) 	{ 		if(head == NULL) 		{ 			head = p1; 		} 		else 			p2->next = p1; 		p2 = p1; 		p1 = (struct node *)malloc(sizeof(struct node)); 		printf("%d: %x\n", ++i, p1); 		//scanf("%d",&p1->num); 	} 	//printf("p2->next=%d\n", p2->next); 	return head; }  int main() { 	node *n = creat(); 	return 0; }  第一个结点编号是0， 之后每个结点编号从1开始。函数返回head。

user: user-2
content: 引用 2 楼 a904235765 的回复:[quote=引用 1 楼 lansong4 的回复:] 看需求是怎样的， 如果程序经常要用到线性表的长度，那么头节点可开个空间存储线性表的长度， 不过在线性表的 添加 和 删除 也要对头节点的长度进行相应的操作。  struct ListNode { ListNode* pNext; int nData; };  struct ListHead {    ListNode* pHead;    int nListLen; }； 那就是说在不需要统计链表的长度时，头结点可以不放数据？ 还有再麻烦你看看这段创建链表的代码： //创建链表 struct node *creat(struct node *head) {     struct node *p1,*p2; 	p1=p2=(struct node *)malloc(sizeof(struct node)); 	printf("%d",p1); 	scanf("%d",&p1->num); 	p1->next=NULL; 	while(p1->num>0) 	{       if(head==NULL) 	  { 	   head=p1; 	  } 	  else 		p2->next=p1;          p2=p1; 	  p1=(struct node *)malloc(sizeof(struct node)); 	  printf("p2=%d",p2); 	  scanf("%d",&p1->num); 	} 	printf("p2->next=%d",p2->next); 	return head; }  	printf("p2->next=%d",p2->next);这一句的输出结果为0，可是在程序中并没有这样的语句啊？输出怎么会是0？  [/quote] 看需求才觉得是否在头里加数据域。 你这段代码本身就有问题，应该是这样的，NULL的整数值就是0，所以输出是0：  struct node *creat(struct node *head) {     struct node *p1,*p2; 	p1=p2=(struct node *)malloc(sizeof(struct node)); 	printf("%d",p1); 	scanf("%d",&p1->num); 	p1->next=NULL; 	while(p1->num>0) 	{       if(head==NULL) 	  { 	   head=p1; 	  } 	  else 		p2->next=p1;          p2=p1;          p2->next=NULL;//加多这句 	  p1=(struct node *)malloc(sizeof(struct node)); 	  printf("p2=%d",p2); 	  scanf("%d",&p1->num); 	} 	printf("p2->next=%d",p2->next); 	return head; }  	printf("p2->next=%d",p2->next);