未排序链表分段错误去除重复元素

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