user-0 提问: C语言 用单链表实现栈的功能 请教pop怎么实现 我这错在哪里

回复:
user: user-0
content: 最终代码献上，谢谢各位的指点。  #include<stdio.h> #include<stdlib.h>  struct node{ 	int data; 	struct node *next; }; struct node *head,*temp,*current;  int length(){ 	int length=0; 	current=head; 	while(current->next!=NULL){ 		length++; 		current=current->next; 	} 	return length; }  void push(int num){ 	struct node *pnode=(struct node*)malloc(sizeof(struct node)); 	pnode->data=num; 	pnode->next=head; 	head=pnode; }  void pop(){ 	if(head->next==NULL) 		return; 	else{ 		temp=head; 		head=head->next; 		free(temp); 		temp=NULL;//避免野指针 		printf("pop successfully!\n"); 	} }  void print(){ 	current=head; 	while(current->next!=NULL){ 		printf("<<---%d",current->data); 		current=current->next; 	} 	printf("\n"); }  void main(){ 	head=(struct node *)malloc(sizeof(struct node)); 	head->next=NULL; 	printf("                  1:length\n"); 	printf("                  2:push\n"); 	printf("                  3:pop\n"); 	printf("                  4:print\n"); 	printf("                  0:exit\n"); 	int choice; 	int number; 	while(1){ 		printf("please enter your choice:"); 		scanf("%d",&choice); 		switch(choice){ 			case 1: 				printf("stack size is:%d\n",length(head));	 				break; 			case 2: 				printf("please enter a number:"); 				scanf("%d",&number); 				push(number); 				print(); 				break; 			case 3: 				pop(); 				print(); 				break; 			case 4: 				print(); 				break; 			case 0:exit(0); 			default: 				printf("wrong choice!\n"); 				break; 		} 	} }

user: user-0
content: 引用 14 楼 neolyao 的回复:这些基本的数据结构 教材上应该有的吧！ 是的，但是我总感觉自己的想法和书上不一样，额，是作死的节奏么。

user: user-1
content: 这些基本的数据结构 教材上应该有的吧！

user: user-0
content: 引用 10 楼 liuhengxiao 的回复:如果你还是想用链表实现栈，而且用尾插的话，你可以用双向循环链表，道理和单链表的头插差不多是一个意思 头插法让我感觉像FIFO而不是LIFO

user: user-0
content: 引用 7 楼 xiaohuh421 的回复:pop是出栈, 你又new一个出来, 明显是不对的.  void pop(){     if(head == NULL)     {           printf("stack is empty!\n");//这里可以打印点东西          return;  //如果头节点也是空, 则还没有任何数据, 直接返回.     }     temp=head; //保存当前的head     head = head->next; //head指向栈中的下一个元素(也就相当于出栈了).     free(temp);  //释放原来的头节点     temp = NULL;  //防止野指针    }  看来我错了，我是应该用头插法和删除首节点，我本来是想实现尾插尾删除的，现在想想，这种方法时间复杂度更大。

user: user-0
content: 引用 9 楼 liuhengxiao 的回复:int main(){     head=(struct node *)malloc(sizeof(struct node));     head=NULL;  应该是head->next=NULL；额，head=NULL是初始栈为空

user: user-2
content: 如果你还是想用链表实现栈，而且用尾插的话，你可以用双向循环链表，道理和单链表的头插差不多是一个意思

user: user-2
content: int main(){     head=(struct node *)malloc(sizeof(struct node));     head=NULL;  应该是head->next=NULL；

user: user-2
content: 栈内也是节点存在，节点与节点之间的联系和链表有什么不同？  实际上栈就等同于链表的头插和首节点删除  看你用个尾插的链表思路去实现栈，这是有什么特殊需求么？

user: user-3
content: pop是出栈, 你又new一个出来, 明显是不对的.  void pop(){     if(head == NULL)     {           printf("stack is empty!\n");//这里可以打印点东西          return;  //如果头节点也是空, 则还没有任何数据, 直接返回.     }     temp=head; //保存当前的head     head = head->next; //head指向栈中的下一个元素(也就相当于出栈了).     free(temp);  //释放原来的头节点     temp = NULL;  //防止野指针    }

user: user-4
content: LIFO，所以改用头插法吧，pop/push不需要去遍历整个链表...

user: user-0
content: 抱歉，代码最后的0是return 0; }  , 复制时出了点小问题

user: user-0
content: 引用 1 楼 u012033027 的回复:while(current->next!=NULL){             current=current->next;         }         temp=current->next;         current->next=temp->next;  wihle之后，current->next == NULL，也就是temp = NULL; 那么，temp->next 就是非法的。 请问我该如何修改呢

user: user-0
content: 对啊，是LIFO，因我我实现的是栈的功能，请指点，我该如何写呢

user: user-5
content: pop是指第一个LIFO吗？ 想想还挺绕的

user: user-6
content: while(current->next!=NULL){             current=current->next;         }         temp=current->next;         current->next=temp->next;  wihle之后，current->next == NULL，也就是temp = NULL; 那么，temp->next 就是非法的。