user-0 提问: 求助关于一个简单的链表实现

回复:
user: user-0
content: 引用 10 楼 qq423399099 的回复:[quote=引用 9楼我是你的主体 的回复:][quote=引用 8 楼 qq423399099 的回复:] [quote=引用 7楼我是你的主体 的回复:][quote=引用 5 楼 user-2 的回复:] #include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; } 我想写的头插是直接在头部的上一个插入比如原来1->5->7头插一个9就变成了9->1->5->7 但是我这样写为什么不对 void add2head(struct node * list, int data){ 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	newnode->data = data; 	newnode->next = list; 	list = newnode; 	return; }[/quote]你要在add2head函数里改变list的指向，必须传二级指针或者一级指针的引用才行[/quote] ....感觉白看了c primer plus，话说为什么要传二级指针或者一级的引用，有没有这方面的资料免得麻烦您了，我一直就以为指针可以任意改变指向，实在不懂为什么还要二级指针才能改变参数的指向[/quote]那是因为你的实参和形参并不是同一个指针，他们只是指向了同一块内存[/quote] 明白了，感谢。

user: user-1
content: 引用 9楼我是你的主体 的回复:[quote=引用 8 楼 qq423399099 的回复:] [quote=引用 7楼我是你的主体 的回复:][quote=引用 5 楼 user-2 的回复:] #include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; } 我想写的头插是直接在头部的上一个插入比如原来1->5->7头插一个9就变成了9->1->5->7 但是我这样写为什么不对 void add2head(struct node * list, int data){ 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	newnode->data = data; 	newnode->next = list; 	list = newnode; 	return; }[/quote]你要在add2head函数里改变list的指向，必须传二级指针或者一级指针的引用才行[/quote] ....感觉白看了c primer plus，话说为什么要传二级指针或者一级的引用，有没有这方面的资料免得麻烦您了，我一直就以为指针可以任意改变指向，实在不懂为什么还要二级指针才能改变参数的指向[/quote]那是因为你的实参和形参并不是同一个指针，他们只是指向了同一块内存

user: user-0
content: 引用 8 楼 qq423399099 的回复:[quote=引用 7楼我是你的主体 的回复:][quote=引用 5 楼 user-2 的回复:] #include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; } 我想写的头插是直接在头部的上一个插入比如原来1->5->7头插一个9就变成了9->1->5->7 但是我这样写为什么不对 void add2head(struct node * list, int data){ 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	newnode->data = data; 	newnode->next = list; 	list = newnode; 	return; }[/quote]你要在add2head函数里改变list的指向，必须传二级指针或者一级指针的引用才行[/quote] ....感觉白看了c primer plus，话说为什么要传二级指针或者一级的引用，有没有这方面的资料免得麻烦您了，我一直就以为指针可以任意改变指向，实在不懂为什么还要二级指针才能改变参数的指向

user: user-1
content: 引用 7楼我是你的主体 的回复:[quote=引用 5 楼 user-2 的回复:] #include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; } 我想写的头插是直接在头部的上一个插入比如原来1->5->7头插一个9就变成了9->1->5->7 但是我这样写为什么不对 void add2head(struct node * list, int data){ 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	newnode->data = data; 	newnode->next = list; 	list = newnode; 	return; }[/quote]你要在add2head函数里改变list的指向，必须传二级指针或者一级指针的引用才行

user: user-0
content: 引用 5 楼 user-2 的回复:#include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; } 我想写的头插是直接在头部的上一个插入比如原来1->5->7头插一个9就变成了9->1->5->7 但是我这样写为什么不对 void add2head(struct node * list, int data){ 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	newnode->data = data; 	newnode->next = list; 	list = newnode; 	return; }

user: user-0
content: 引用 4 楼 qq423399099 的回复:你这句其实会造成内存泄漏struct node * head = (struct node *)malloc(sizeof(struct node *)); 你这个链表根本就是不带头结点的链表，你为head指针malloc了4个字节的空间，之后马上让它指向了n 之前malloc的4个字节的地址你已经丢失了，struct node * head = (struct node *)malloc(sizeof(struct node *));这句完全可以去掉。  但是如果去掉，head就变成了auto变量，它会在函数调用结束后回收吧？

user: user-2
content: #include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; }

user: user-1
content: 你这句其实会造成内存泄漏struct node * head = (struct node *)malloc(sizeof(struct node *)); 你这个链表根本就是不带头结点的链表，你为head指针malloc了4个字节的空间，之后马上让它指向了n 之前malloc的4个字节的地址你已经丢失了，struct node * head = (struct node *)malloc(sizeof(struct node *));这句完全可以去掉。

user: user-1
content: 引用 11楼我是你的主体 的回复:[quote=引用 10 楼 qq423399099 的回复:] [quote=引用 9楼我是你的主体 的回复:][quote=引用 8 楼 qq423399099 的回复:] [quote=引用 7楼我是你的主体 的回复:][quote=引用 5 楼 user-2 的回复:] #include<iostream>  #include<malloc.h> using namespace std;  typedef struct Node { 	int data; 	Node *next; }Lnode,*List;  int Allocate(List &p) //必须要有引用，否则指针p分不到内存空间  {   p=(List)malloc(sizeof(Lnode));   p->next=NULL;   return 0; }  int HeadCreatlist(List p1)  //头插法  {   List s;     Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   s->next=p1->next;   p1->next=s;   return 0; }  int TailCreatlist(List &p3) //尾插法  {   List s;    Allocate(s);   cout<<"Please input the data"<<endl;   cin>>s->data;   p3->next=s;   p3=s;   return 0; }  int Travellist(List P) //遍历函数  {   List p=P->next;   while(p!=NULL)   {   	cout<<p->data<<" ";   	p=p->next;   }   return 0; }  int main() {   List p1;   int i;   Allocate(p1);   for(int i=0;i<4;i++)   HeadCreatlist(p1);   Travellist(p1); //头插法用的代码       List p2;   Allocate(p2);   List p3=p2; //尾插法用的存储当前指针   for(int i=0;i<4;i++)  TailCreatlist(p3);  Travellist(p2);//尾插法用的代码     return 0; } 我想写的头插是直接在头部的上一个插入比如原来1->5->7头插一个9就变成了9->1->5->7 但是我这样写为什么不对 void add2head(struct node * list, int data){ 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	newnode->data = data; 	newnode->next = list; 	list = newnode; 	return; }[/quote]你要在add2head函数里改变list的指向，必须传二级指针或者一级指针的引用才行[/quote] ....感觉白看了c primer plus，话说为什么要传二级指针或者一级的引用，有没有这方面的资料免得麻烦您了，我一直就以为指针可以任意改变指向，实在不懂为什么还要二级指针才能改变参数的指向[/quote]那是因为你的实参和形参并不是同一个指针，他们只是指向了同一块内存[/quote] 明白了，感谢。[/quote]解决了记得结帖

user: user-0
content: 引用 2 楼 qq423399099 的回复:因为你的add2tail根本没有将新结点连接上。 1.add2tail函数里while (n != NULL)改成while (n->next != NULL) 2.n= newnode;改成n->next = newnode;  #include <stdio.h> #include <stdlib.h> #include <stdbool.h>  struct node{ 	int data; 	struct node * next; };   struct node *  init(int data){ 	struct node * head = (struct node *)malloc(sizeof(struct node *)); 	struct node *  n = (struct node *)malloc(sizeof(struct node)); 	n->data = data; 	n->next = NULL; 	head = n; 	return head; }  void add2tail(struct node *  list, int data){ 	struct node *  n = list; 	while (n->next != NULL){ 		n = n->next; 	} 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	n->next = newnode; 	newnode->data = data; 	newnode->next = NULL; 	return; }  void print(struct node *  list){ 	struct node *  n = list; 	while (n != NULL){ 		printf("%d ", n->data); 		n = n->next; 	} 	printf("\n"); 	return; }  int main(void){ 	struct node *  head = init(123); 	print(head); 	add2tail(head, 7); 	print(head); 	system("pause"); 	return 0; }  感谢您，我尝试了一下的确可以，我等下再想想原因 另外还有一个问题想麻烦您一下，我突然觉得struct node * head = (struct node *)malloc(sizeof(struct node *));会不会有点多余或者有点错误，malloc根据我的理解是为指针所指向的内容分配内存，这里指向的是一个节点却只分配了sizeof(struct node *)的大小会不会有点问题，求教正确的该这么改

user: user-1
content: 因为你的add2tail根本没有将新结点连接上。 1.add2tail函数里while (n != NULL)改成while (n->next != NULL) 2.n= newnode;改成n->next = newnode;  #include <stdio.h> #include <stdlib.h> #include <stdbool.h>  struct node{ 	int data; 	struct node * next; };   struct node *  init(int data){ 	struct node * head = (struct node *)malloc(sizeof(struct node *)); 	struct node *  n = (struct node *)malloc(sizeof(struct node)); 	n->data = data; 	n->next = NULL; 	head = n; 	return head; }  void add2tail(struct node *  list, int data){ 	struct node *  n = list; 	while (n->next != NULL){ 		n = n->next; 	} 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	n->next = newnode; 	newnode->data = data; 	newnode->next = NULL; 	return; }  void print(struct node *  list){ 	struct node *  n = list; 	while (n != NULL){ 		printf("%d ", n->data); 		n = n->next; 	} 	printf("\n"); 	return; }  int main(void){ 	struct node *  head = init(123); 	print(head); 	add2tail(head, 7); 	print(head); 	system("pause"); 	return 0; }

user: user-0
content: 在线急求