【问题标题】:C++ Removing and Deleting a NodeC++ 删除和删除节点
【发布时间】:2020-05-01 19:12:48
【问题描述】:

我第一次使用指针,并试图编写一个删除节点的函数和一个删除节点的函数。我的代码在我插入键和数据时识别(例如:键 = 123,数据 = 123)。但是,当我尝试删除密钥 123 时,它无法识别它的存在。这是我的 LList.cpp,如果需要,我可以包含其他代码:

#include <iostream>
#include "LList.h"

//----------------------------------------------------
//             constructor & destructor
//----------------------------------------------------
LList::LList() {
    head = NULL;
} // constructor (default)
LList::~LList() {
    if (head) delete head;
} // destructor


//----------------------------------------------------
//                  print
//----------------------------------------------------
// prints each node in the list, or EMPTY when there
// are no nodes to print
//----------------------------------------------------
void LList::print() {
    if (head == NULL)
        cout << "EMPTY\n\n";
    else {
        node* p;
        p = head;
        while (p != NULL) {
            p->print();
            p = p->next;
        }
        cout << endl;
    }
} // print()

//----------------------------------------------------
//                       search
//----------------------------------------------------
// Given: key to search for
// Returns: pointer to a node in the list found to have
//          the given search key, or NULL for not found
//----------------------------------------------------
node* LList::search(int srchKey) {
    if (head == NULL)
        return NULL;
    node* itr = head;
    while (itr != NULL) {
        if (itr->key == srchKey)
            itr = itr->next;
    }
    return itr;
} // search()

//----------------------------------------------------
//                 findNode
//----------------------------------------------------
// Given: a key to search for
// Searches for a node with the given key, and if 
// found, invokes the print() method in the found node.
// Otherwise, prints "not found"
//----------------------------------------------------
void LList::findNode(int srchkey) {
    if (head == NULL) {
        cout << "not found\n";
    }
    node* itr = head;
    while (itr != NULL) {
        if (itr->key == srchkey) {
            print();
        }
        itr = itr->next;
    }
    cout << "not found\n";
} // findNode()

//----------------------------------------------------
//                  getb4
//----------------------------------------------------
// Given: a pointer to a node in the list
// Returns: a pointer to the node in the list BEFORE
//               the one pointed to by r, OR
//          NULL when r is the head or not found in
//               the list
//----------------------------------------------------
node* LList::getb4(node* r) {
    node* tmp = head;
    while (tmp->next != NULL) {
        if (tmp->next == r)
            return tmp;
        tmp = tmp->next;
    }
    return NULL;
} // getb4()

//----------------------------------------------------
//                     insert
//----------------------------------------------------
// Given: key and data for a new node
// Allocates/populates a new node
// When a node with the same key already exists:
//     the current/old node is replaced by the new one
//     and the old one is placed on the new one's 
//     duplicate list.
// Otherwise, the new node is prepended to the head
//     of the list.
//----------------------------------------------------
void LList::insert(int k, string d) {
    node* newNode = new node();
    node* currentNode, *prevNode;
    newNode->key = k;
    newNode->data = d;
    if (head == NULL) {
        head = newNode;
    }
    else {
        currentNode = search(k);
        if (currentNode == NULL) {
            newNode->next = head;
            head = newNode;
        }
        if (currentNode == head) {
            newNode->next = head->next;
            head->next = NULL;
            newNode->dup = head;
            head = newNode;
        }
        prevNode = getb4(currentNode);
        if (prevNode == NULL)
            return;
        prevNode->next = newNode;
        //newNode->next = currentNode->next;
        currentNode->next = NULL;
        newNode->dup = currentNode;
    }
} // insert()

//----------------------------------------------------
//                     remove
//----------------------------------------------------
// Given: a pointer to a node in the list to be removed
//        BUT NOT DELETED/DESTROYED
// Returns: TRUE - when the node was successfully removed
//          FALSE - when the given node is NULL or the node
//                  is not actually in the list.
// Simply removes the node from the linked list.
// (including setting the NEXT pointer in the node to NULL)
//----------------------------------------------------
bool LList::remove(node* r) {
    if (r == NULL || search(r->key) == NULL) {
        return false;
    }
    if (r == head) {
        head = head->next;
    }
    else {
        node* prev = getb4(r);
        prev->next = r->next;
    }
    r->next = NULL;
    return true;
} // remove()

//----------------------------------------------------
//                     drop
//----------------------------------------------------
// Given: key of a node to drop
// Returns: TRUE when a node was found and deleted
//          FALSE when a node with the given key not found,
//                or the remove() fails.
// Searches for a node in the list with the given key:
// When found, removes and deletes the node
//----------------------------------------------------
bool LList::drop(int k) {
    node* currentNode = search(k);
    if (currentNode == NULL || !remove(currentNode))
        return false;
    node* tmp = currentNode;
    while (tmp != NULL) {
        currentNode = currentNode->dup;
        remove(tmp);
        tmp = currentNode;
    }
    return true;
} // drop()

//----------------------------------------------------
//                      max
//----------------------------------------------------
// Returns: a pointer to the node with the highest key
//          or NULL when there list is empty.
node* LList::max() {
    if (head == NULL)
        return NULL;
    node* max = head;
    node* tmp = head->next;
    while (tmp != NULL) {
        if ((tmp->key) > (max->key)) {
            max = tmp;
        }
        tmp = tmp->next;
    }
    return max;
} // max()

【问题讨论】:

  • 1) LList.h -- 需要发布。 2) 需要发布一个重复问题的main 程序。 3)您应该在发布之前从代码中删除 cmets。 4)使用您正在使用的编译器附带的调试器。如果你这样做,那么你很可能会自己发现问题。
  • 在这个答案stackoverflow.com/a/22122095 中查看社区添加。使用的指针对指针技巧消除了对 getb4 函数的需要。
  • 我相信您的 search 函数将始终返回 NULL ,除非您要搜索的项目是第一个元素,因为您的 while 循环与您认为的相反 == 应该是!=,以及其他几个问题,从那里开始。
  • 另外,链表不是二叉搜索树

标签: c++ pointers binary-search-tree nodes


【解决方案1】:

这个循环:

 while (itr != NULL) {
        if (itr->key == srchKey)
            itr = itr->next;
    }
 return itr;

不正确。如果找到密钥,您要么进行迭代,要么根本不进行迭代。您需要遍历列表,在这样做的同时搜索键:

 while (itr != NULL) {
        if (itr->key == srchKey)
            break;
        itr = itr->next;
    }
 return itr;

另外,你的析构函数不正确;您只删除了第一个节点,并泄漏了其余节点。您需要通过遍历链表来删除所有节点:

LList::~LList() {
    while (head) 
        delete std::exchange(head, head->next);
}

另外,更喜欢使用nullptr,而不是NULL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2019-05-10
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多