【问题标题】:Deletion of specific node from singly Linked list with the help of data given在给定数据的帮助下从单链表中删除特定节点
【发布时间】:2017-09-07 04:51:51
【问题描述】:

我正在尝试删除特定数据的节点。为此,我正在使用 deleteNode 函数但无法删除。请看代码:

#include<iostream>
using namespace std;

class node
{
    public:
    int data;
    node* next;

    ///constructor for initializing the data-

    node(int d)
    {
        data=d;
        next=NULL;
    }

};
void addAtEnd(node* &head,int data)
{
    if(head==NULL)
    {
        head=new node(data);
        return ;
    }
  node* temp=head;
  while(temp->next!=NULL)
  {
      temp=temp->next;
  }
  node* n =new node(data);
  n->data=data;
  temp->next=n;
  n->next=NULL;
  return;
}
AddAtTail(node* head,int d)
{
  node* ptr=head;
  while(ptr->next!=NULL)
  {
      ptr=ptr->next;
  }
  node *n=new node(d);
  ptr->next=n;
  n->next=NULL;


}
AddAtPosition(node* head,int p,int d)
{

    ///2 3 4 6 7 8 -1
    ///4th Position-
    node*ptr=head;
    int jump=1;
    while(jump<=p-1)
    {
        jump++;
        ptr=ptr->next;
    }
    node*n=new node(d);
    n->next=ptr->next;
    ptr->next=n;


}

/// Delete First node
void deleteFirst(node *&head)
{
    head=head->next;

}

///Delete last node;
void deleteLast(node* head)
{
  node* ptr=head;
  while(ptr->next->next!=NULL)
  {
      ptr=ptr->next;
  }
  ptr->next=NULL;
}
**///Delete Specific Node  :-**

这里函数开始删除节点。我正在尝试删除具有数据的节点 3 我正在将数据作为主函数的输入。

void deleteData(node* head,int d)
{
    node*ptr=head;
    while(ptr->next!=NULL)
    {
       if(ptr->next->data==d)
       {
         ptr=ptr->next->next;
         return;
       }
       ptr=ptr->next;
    }
}


void takeInput(node*& head)
{

    int d;
    cin>>d;
    while(d!=-1)
    {
      addAtEnd(head,d);
      cin>>d;

    }
}
void print(node* head)
{
    while(head!=NULL)
    {
        cout<<head->data<<"=>";
        head=head->next;
    }
}
AddAtFront(node* &head,int d)
{
   ///create new node;
   node*n=new node(d);
   n->next=head;
   head=n;


}

int main()
{
    node* head(NULL);
    takeInput(head);
    print(head);
    cout<<endl<<endl<<endl<<"---------- Here The Insertion Process starts at different Positions -----------"<<endl;
    cout<<endl<<"Adding at Tail"<<endl;

    AddAtTail(head,9);
    print(head);
    cout<<endl<<"Adding at Position p"<<endl;
    int p,d;

    cout<<"Enter Position and data :"<<endl;
    cin>>p>>d;
    AddAtPosition(head,p,d);
    print(head);
    cout<<endl<<"Adding at Front"<<endl;
    cout<<"Enter data to add at front : "<<endl;
    cin>>d;
    AddAtFront(head,d);

    print(head);
    cout<<endl<<endl<<endl;
    cout<<endl<<"--------------------  NOW LETS PERFORM DELETION  ------------------"<<endl;
    cout<<endl<<"Deleting first node :"<<endl;
    deleteFirst(head);
    print(head);
    cout<<endl;
    cout<<endl<<"Deleting Last node :"<<endl;
    deleteLast(head);
    print(head);
    cout<<endl;
    cout<<"deleting specific node"<<endl;
    cout<<"Enter data to delete"<<endl;
    cin>>d;
    deleteData(head,d);
    print(head);
    cout<<endl;

    return 0;
}

请参阅我试图删除节点的 DeleteNode 函数。 为什么节点不删除?这是函数:

**///Delete Specific Node i.e- data :-**
    void deleteData(node* head,int d)
    {
        node*ptr=head;
        while(ptr->next!=NULL)
        {
           if(ptr->next->data==d)
           {
             ptr=ptr->next->next;
             return;
           }
           ptr=ptr->next;
        }
    }

但节点没有删除。

【问题讨论】:

  • 离题:你new你也应该delete
  • 建议修复缺少返回类型的函数。
  • 程序由于列表中的循环而挂起,然后我才能复制您的问题。您有多个错误。
  • 使用 mark-1 眼球,ptr=ptr-&gt;next-&gt;next; 修改了一个临时本地并且不改变列表。
  • deleteData : 1) 从不检查 head 是否为 NULL 2) 从不检查 head 持有的数据 3) ptr=ptr-&gt;next-&gt;next; 是错误的。也许ptr-&gt;next=ptr-&gt;next-&gt;next; 4) 从不打电话给delete

标签: c++ linked-list singly-linked-list


【解决方案1】:

您的delete... 函数实际上并没有删除任何内容。您只是在操作指针,但正在泄漏实际的 node 对象。而且您没有考虑到被删除的节点是head 节点的可能性,这需要更新head 以指向下一个节点。

此外,您的函数将在空列表上崩溃,deleteLast 将在少于 2 个节点的列表上崩溃。

deleteData 没有正确枚举节点。

试试类似的方法:

#include <iostream>
using namespace std;

class node {
public:
    int data;
    node* next;

    ///constructor for initializing the data-

    node(int d) {
        data=d;
        next=NULL;
    }
};

node* findLast(node *head, node **before) {
    if (before) *before = NULL;
    node *last = head;
    if (last) {
        while (last->next) {
            if (before) *before = last;
            last = last->next;
        }
    }
    return last;
}

node* addAtFront(node* &head, int data) {
    node* n = new node(data);
    n->next = head;
    head = n;
    return n;
}

node* addAtEnd(node* &head, int data) {
    node *last = findLast(head, NULL);
    node* n = new node(data);
    if (last) {
        last->next = n;
    } else {
        head = n;
    }
    return n;
}

node* addAtPosition(node* &head, int p, int d) {
    if ((!head) || (p <= 0)) {
        return addAtFront(head, d);
    }
    node *ptr = head;
    node *temp;
    do {
        temp = ptr;
        ptr = ptr->next;
    }
    while ((ptr) && (--p > 0));
    node *n = new node(d);
    n->next = temp->next;
    temp->next = n;
    return n;
}

/// Delete First node
void deleteFirst(node* &head) {
    if (head) {
        node *ptr = head;
        head = head->next;
        delete ptr;
    }
}

///Delete last node
void deleteLast(node* &head) {
    node *beforeLast;
    node *last = findLast(head, &beforeLast);
    if (last) {
        if (beforeLast) {
            beforeLast->next = NULL;
        }
        if (head == last) {
            head = NULL;
        }
        delete last;
    }
}

///Delete Specific Node
void deleteData(node* &head, int d) {
    node *before = NULL;
    node *ptr = head;
    while (ptr) {
        if (ptr->data == d) {
            if (before) {
                before->next = ptr->next;
            }
            if (head == ptr) {
                head = head->next;
            }
            delete ptr;
            return;
        }
        before = ptr;
        ptr = ptr->next;
    }
}

void takeInput(node* &head) {
    int d;
    if (!((cin >> d) && (d != -1))) return;
    node *last = findLast(head, NULL);
    node *n = new node(d);
    if (last) {
        last->next = n;
    } else {
        head = n;
    }
    last = n;
    while ((cin >> d) && (d != -1)) {
        n = new node(d);
        last->next = n;
        last = n;
    }
}

void print(node* head) {
    while (head) {
        cout << head->data << "=>";
        head = head->next;
    }
}

int main() {
    node* head = NULL;

    takeInput(head);
    print(head);
    cout << endl;

    cout << endl << endl;
    cout <<     "---------- Here The Insertion Process starts at different Positions -----------" << endl << endl;

    cout << "Adding at End" << endl;
    addToEnd(head, 9);
    print(head);
    cout << endl;

    cout << "Adding at Position p" << endl;
    int p, d;
    cout << "Enter Position and data :" << endl;
    if (cin >> p >> d) {
        addAtPosition(head, p, d);
        print(head);
        cout << endl;
    } 

    cout << "Adding at Front" << endl;
    cout << "Enter data to add at front : " << endl;
    if (cin >> d) {
        addAtFront(head, d);
        print(head);
        cout << endl;
    } 

    cout << endl << endl << endl;
    cout << "-------------------- NOW LETS PERFORM DELETION ------------------" << endl << endl;

    cout << "Deleting first node :" << endl;
    deleteFirst(head);
    print(head);
    cout << endl;

    cout << endl << "Deleting Last node :" << endl;
    deleteLast(head);
    print(head);
    cout << endl;

    cout << "deleting specific node" << endl;
    cout << "Enter data to delete" << endl;
    if (cin >> d) {
        deleteData(head, d);
        print(head);
        cout << endl;
    }

    cout << "deleting remaining nodes" << endl;
    node *ptr = head;
    while (ptr) {
        node *temp = ptr;
        ptr = ptr->next;
        delete temp;
    }

    return 0;
}

话虽如此,您确实应该改用std::list(双链接)或std::forward_list(单链接)。让 STL 为您完成繁重的工作。

【讨论】:

    【解决方案2】:
    1. 在删除节点函数中,您正在更改局部变量 ptr 的值。但是您并没有更改指向要删除的节点的“下一个”指针。所以它保留在列表中。离开函数后,本地指针的值就变得无关紧要。 这行是问题所在:ptr=ptr-&gt;next-&gt;next;

    您需要更改其“下一个”值。类似的东西(我还没有编译和测试过这个;建议你指出正确的方向。)

    void deleteData(node* head,int d)
    {
        node*ptr=head;
    
        while(ptr->next!=NULL)
        {
           if(ptr->next->data==d)
           { /* pointer->next points to the node you want to delete.  
                point it instead to the one beyond */
             ptr->next=ptr->next->next;
             return;
           }
    
           ptr=ptr->next;
        }
    }
    
    1. 然后您将发生内存泄漏,因为您没有将内存释放到要删除的节点。

    你需要类似的东西:

    void deleteData(node* head,int d)
    {
        node*ptr=head;
    
        while(ptr->next!=NULL)
        {
            if(ptr->next->data==d)
            { /* pointer->next points to the node you want to delete.  
                 point it instead to the one beyond, 
                 freeing the memory of the deleted node */
                 node * pNodeToDelete = ptr->next;                      
                 ptr->next=ptr->next->next;
                 free(pNodeToDelete)
                 return;
            }
    
            ptr=ptr->next;
        }
    }
    

    【讨论】:

    • 如果有人知道如何在代码块中获取我的最后一个大括号,请编辑它,或者更好的是,告诉我如何。是的,当我按下 {} 按钮时,我与其余代码块一起选择了它。当已经在代码块中时,我也尝试将其删除并重新插入......谢谢!
    • ptr->next=ptr->next->next; .但是当我将它存储在指针中时,程序没有给出正确的输出。所以我没有释放内存
    • 我不明白您的最后一条评论——“但是当我将它存储在指针中时,程序没有给出正确的输出”是什么意思?你期望它没有给出什么输出? “当我将它存储在指针中时”是什么意思?
    • @kindacoder -- 现在对你有用吗?我不明白你的最后一个问题,在我最后一个上面的评论中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多