未排序链表分段错误去除重复元素
Segmentation fault removal duplicate elements in unsorted linked list
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
int data;
struct node* next;
};
struct node* head;
void traversalLinkedList(struct node* ptr){
if(ptr==NULL) {cout<<"null hain bhai"<<endl; return;}
while(ptr!=NULL){
cout<<ptr->data<<" ";
ptr=ptr->next;
}
}
void push(int d){
//at the front of linked list
struct node* temp=(struct node*) malloc(sizeof(struct node));
temp->data=d;
temp->next=head;
head=temp;
}
int main(){
head=NULL;
//removing duplicates from linked list
push(10);
push(11);
push(12);
push(11);
push(11);
push(12);
push(10);
traversalLinkedList(head);
struct node *ptr;
struct node* prev;
struct node* qtr;
for(ptr=head;ptr->next!=NULL;ptr=ptr->next){
prev=ptr;
for(qtr=ptr->next;qtr!=NULL;){
if(ptr->data==qtr->data){
//means duplicate nodes
prev->next=qtr->next;
free(qtr);
qtr=prev->next;
}
else{
prev=qtr;
qtr=qtr->next;
}
}
}
cout<<endl;
traversalLinkedList(head);
cout<<endl;
return 0;
}
我无法理解为什么我会收到此代码的分段错误。此代码是从未排序的链表中删除重复元素。
说明
一旦发现内循环节点数据等于外循环节点数据,我就使用前一个指针存储内循环指针之前的节点,使前一个指针指向内循环节点的下一个指针和内循环节点被释放。
for循环中的这个条件ptr->next!=NULL
是有问题的。
for(ptr=head;ptr->next!=NULL;ptr=ptr->next)
它将取消引用最后一个节点的 NULL
指针。应该是:
for(ptr=head;ptr!=NULL;ptr=ptr->next)
for(ptr=head;ptr->next!=NULL;ptr=ptr->next){
应该是
for(ptr=head;ptr!=NULL;ptr=ptr->next){
它失败了,因为最后只剩下两个 12,而 ptr 指向其中一个。它的下一个不为空,因此您进入迭代。在该迭代中,您删除了第二个 12,因此 ptr 的下一个现在为空。然后迭代结束,你设置 ptr 为 ptr->next,所以 ptr 本身变为 null,然后你检查 ptr->next 是否为 null,并在那里崩溃。
编辑:如果您想跳过最后一个元素,请执行
for(ptr=head;ptr && ptr->next!=NULL;ptr=ptr->next){
for(ptr=head;ptr->next!=NULL;ptr=ptr->next)
在这一行中,当您说 ptr->next!=NULL 时,最后一个节点将取消引用空指针。这会导致分段错误,因为您正在尝试访问空指针。
所以,把第二个条件设为ptr!=NULL
就可以了。这已经足够了,因为无论如何你在 for
循环
的第三个条件下做 ptr=ptr->next
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
int data;
struct node* next;
};
struct node* head;
void traversalLinkedList(struct node* ptr){
if(ptr==NULL) {cout<<"null hain bhai"<<endl; return;}
while(ptr!=NULL){
cout<<ptr->data<<" ";
ptr=ptr->next;
}
}
void push(int d){
//at the front of linked list
struct node* temp=(struct node*) malloc(sizeof(struct node));
temp->data=d;
temp->next=head;
head=temp;
}
int main(){
head=NULL;
//removing duplicates from linked list
push(10);
push(11);
push(12);
push(11);
push(11);
push(12);
push(10);
traversalLinkedList(head);
struct node *ptr;
struct node* prev;
struct node* qtr;
for(ptr=head;ptr->next!=NULL;ptr=ptr->next){
prev=ptr;
for(qtr=ptr->next;qtr!=NULL;){
if(ptr->data==qtr->data){
//means duplicate nodes
prev->next=qtr->next;
free(qtr);
qtr=prev->next;
}
else{
prev=qtr;
qtr=qtr->next;
}
}
}
cout<<endl;
traversalLinkedList(head);
cout<<endl;
return 0;
}
我无法理解为什么我会收到此代码的分段错误。此代码是从未排序的链表中删除重复元素。
说明 一旦发现内循环节点数据等于外循环节点数据,我就使用前一个指针存储内循环指针之前的节点,使前一个指针指向内循环节点的下一个指针和内循环节点被释放。
for循环中的这个条件ptr->next!=NULL
是有问题的。
for(ptr=head;ptr->next!=NULL;ptr=ptr->next)
它将取消引用最后一个节点的 NULL
指针。应该是:
for(ptr=head;ptr!=NULL;ptr=ptr->next)
for(ptr=head;ptr->next!=NULL;ptr=ptr->next){
应该是
for(ptr=head;ptr!=NULL;ptr=ptr->next){
它失败了,因为最后只剩下两个 12,而 ptr 指向其中一个。它的下一个不为空,因此您进入迭代。在该迭代中,您删除了第二个 12,因此 ptr 的下一个现在为空。然后迭代结束,你设置 ptr 为 ptr->next,所以 ptr 本身变为 null,然后你检查 ptr->next 是否为 null,并在那里崩溃。
编辑:如果您想跳过最后一个元素,请执行
for(ptr=head;ptr && ptr->next!=NULL;ptr=ptr->next){
for(ptr=head;ptr->next!=NULL;ptr=ptr->next)
在这一行中,当您说 ptr->next!=NULL 时,最后一个节点将取消引用空指针。这会导致分段错误,因为您正在尝试访问空指针。
所以,把第二个条件设为ptr!=NULL
就可以了。这已经足够了,因为无论如何你在 for
循环
ptr=ptr->next