user-0 提问: 非循环双链表逆向输出的问题!

回复:
user: user-1
content: #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h>   typedef struct List {     int ldata;        //数据域     List* pier;        //前驱节点     List* pnext;        //后继节点  }*plist,list;  plist lcreate() {     list* lhead, *lend, *lnew;     int num,data;     int icount;     lhead = (list*)malloc(sizeof(list));     if (lhead == NULL)     {         printf("内存申请失败!\n");         exit(-1);     }     lhead->pnext = NULL;     lhead->pier = NULL; /* note: init pier */     lend = lhead;     lend->pnext = NULL;     printf("需要输入多少位数据:");     scanf_s("%d",&num);     for (icount = 0; icount < num; icount++)     {          printf("输入数据:");         scanf_s("%d", &data);         lnew = (list*)malloc(sizeof(list));         if (lnew == NULL)         {             printf("内存申请失败!\n");             exit(-1);         }          lnew->ldata = data;         lnew->pnext = lend->pnext;         lnew->pier = lend;         lend->pnext = lnew;         lend = lnew;      }     lend->pnext = NULL;     return lhead; } //在第i个节点前添加数据 plist inserchlist(list* head,int data,int num) {     list* p,*pnew;     int findnum;     p = head->pnext;     for (findnum = 1; findnum < num; findnum++)     {         p = p->pnext;     }     pnew = (list*)malloc(sizeof(list));     pnew->ldata = data;      pnew->pier = p->pier;     pnew->pnext = p;     p->pier->pnext = pnew;     p->pier = pnew;      return head; } //在第i个节点后插入数据 plist nextinserch(list* head, int data, int num) {     list* p, *nnext;     p = head->pnext;     int findnum;     for (findnum = 1; findnum < num; findnum++)     {         p = p->pnext;     }      nnext = (list*)malloc(sizeof(list));     nnext->ldata = data;     if (p->pnext!=NULL)     {         p = p->pnext;         nnext->pier = p->pier;         nnext->pnext = p;         p->pier->pnext = nnext;         p->pier = nnext;     }     else     {         nnext->pier = p;         nnext->pnext = p;         p->pnext = nnext;         p->pnext->pier = NULL;         p = nnext;         p->pnext = NULL;     }     return head; } //顺序输出数据 void prit(list* head) {     list* p;     p = head->pnext;     if (head == NULL)     {         printf("空链表!\n");         exit(-1);     }     while (p!=NULL)     {          printf("数据为:%d\n",p->ldata);         p = p->pnext;     }  } //逆置输出数据 void pierpirt(list* head) {     list* p;     p = head->pnext;      //while (p != NULL)     while (p->pnext != NULL)     {         printf("顺序打印,节点元数为:%d\n",p->ldata);          p = p->pnext;         //这个循环体中，p是正常的，断点调试，看到p的next都有值，在每个next的上面pier（即前驱节点也有值）。      }     //上面的循环之后，p应该到链尾。断点调试在p循环出来之后，p却是内存无法读取。     if (p == NULL)     {         printf("前驱为空!\n");         exit(-1);     }      //while (p->pier != head)     while (p->pier != NULL)     {         printf("逆向输出的数据为:%d\n",p->ldata);         p = p->pier;     } }  int _tmain(int argc, _TCHAR* argv[]) {     list* temp;     int tdata,tnum;     int lastdata, lastnum;     temp = lcreate();     prit(temp);     //在第i个节点前添加数据     printf("输入要添加的数据:");     scanf_s("%d",&tdata);     printf("输入要添加的节点:");     scanf_s("%d", &tnum);     temp=inserchlist(temp, tdata, tnum);     prit(temp);      //在第i个节点后添加数据     printf("输入要添加的数据:");     scanf_s("%d", &lastdata);     printf("输入要添加的节点:");     scanf_s("%d", &lastnum);     temp=nextinserch(temp, lastdata,lastnum);     /*prit(temp);*/     //逆置输出数据     pierpirt(temp);     return 0; } 逆向输出问题解决了，对比看一下；改了2句，加了一句。加的一句是在创建双向链表时，初始化了头节点的前置指针。

user: user-2
content: 因为你是while (p != NULL)，当结束while循环时p是NULL，所以你判断if (p == NULL)就是true了，就exit了 两个问题： 1.你的顺序打印中，应该判断改成这样while (p->pnext != NULL)，然后先p = p->pnext;才行 2.你的逆序打印中，判断应该是while (p != head)才对  #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct List { 	int ldata;        //数据域 	List* pier;        //前驱节点    	List* pnext;        //后继节点  }*plist, list;  plist lcreate() { 	list* lhead, *lend, *lnew; 	int num, data; 	int icount; 	lhead = (list*)malloc(sizeof(list)); 	if (lhead == NULL) 	{ 		printf("内存申请失败!\n"); 		exit(-1); 	} 	lhead->pnext = NULL; 	lend = lhead; 	lend->pnext = NULL; 	printf("需要输入多少位数据:"); 	scanf_s("%d", &num); 	for (icount = 0; icount < num; icount++) 	{  		printf("输入数据:"); 		scanf_s("%d", &data); 		lnew = (list*)malloc(sizeof(list)); 		if (lnew == NULL) 		{ 			printf("内存申请失败!\n"); 			exit(-1); 		}  		lnew->ldata = data; 		lnew->pnext = lend->pnext; 		lnew->pier = lend; 		lend->pnext = lnew; 		lend = lnew;  	} 	lend->pnext = NULL; 	return lhead; } //在第i个节点前添加数据 plist inserchlist(list* head, int data, int num) { 	list* p, *pnew; 	int findnum; 	p = head->pnext; 	for (findnum = 1; findnum < num; findnum++) 	{ 		p = p->pnext; 	} 	pnew = (list*)malloc(sizeof(list)); 	pnew->ldata = data;  	pnew->pier = p->pier; 	pnew->pnext = p; 	p->pier->pnext = pnew; 	p->pier = pnew;  	return head; } //在第i个节点后插入数据 plist nextinserch(list* head, int data, int num) { 	list* p, *nnext; 	p = head->pnext; 	int findnum; 	for (findnum = 1; findnum < num; findnum++) 	{ 		p = p->pnext; 	}  	nnext = (list*)malloc(sizeof(list)); 	nnext->ldata = data; 	if (p->pnext != NULL) 	{ 		p = p->pnext; 		nnext->pier = p->pier; 		nnext->pnext = p; 		p->pier->pnext = nnext; 		p->pier = nnext; 	} 	else 	{ 		nnext->pier = p; 		nnext->pnext = p; 		p->pnext = nnext; 		p->pnext->pier = NULL; 		p = nnext; 		p->pnext = NULL; 	} 	return head; } //顺序输出数据 void prit(list* head) { 	list* p; 	p = head->pnext; 	if (head == NULL) 	{ 		printf("空链表!\n"); 		exit(-1); 	} 	while (p != NULL) 	{  		printf("数据为:%d\n", p->ldata); 		p = p->pnext; 	}  } //逆置输出数据 void pierpirt(list* head) { 	list* p; 	p = head;  	while (p->pnext != NULL) 	{ 		p = p->pnext; 		printf("顺序打印,节点元数为:%d ", p->ldata);  		 		//这个循环体中，p是正常的，断点调试，看到p的next都有值，在每个next的上面pier（即前驱节点也有值）。  	} 	//上面的循环之后，p应该到链尾。断点调试在p循环出来之后，p却是内存无法读取。 	if (p == NULL) 	{ 		printf("前驱为空!\n"); 		exit(-1); 	} 	printf("\n"); 	while (p != head) 	{ 		printf("逆向输出的数据为:%d\n", p->ldata); 		p = p->pier; 	} }  int _tmain(int argc, _TCHAR* argv[]) { 	list* temp; 	int tdata, tnum; 	int lastdata, lastnum; 	temp = lcreate(); 	prit(temp);  	//在第i个节点前添加数据 	printf("输入要添加的数据:"); 	scanf_s("%d", &tdata); 	printf("输入要添加的节点:"); 	scanf_s("%d", &tnum); 	temp = inserchlist(temp, tdata, tnum); 	prit(temp);  	//在第i个节点后添加数据 	printf("输入要添加的数据:"); 	scanf_s("%d", &lastdata); 	printf("输入要添加的节点:"); 	scanf_s("%d", &lastnum); 	temp = nextinserch(temp, lastdata, lastnum); 	/*prit(temp);*/  	//逆置输出数据 	pierpirt(temp); 	return 0; }

user: user-0
content: 谢谢各位前辈。