删除两个列表中的指针

时间:2016-05-23 17:49:47

标签: c++ linked-list

我有一个链表数组,每个数组索引都包含链表。

除此之外,我还有另一个链表,按照我输入的确切顺序保存节点。

所以举个例子。 我的数组有500个索引。我在索引1上输入一个节点,在索引2上输入一个节点。 当我在索引1上打印链表时,它将只打印一个节点。但是,当我打印保存输入节点的确切顺序的链接列表时,它将按照我输入的顺序打印它们。

我已使用此代码

实现了此功能
class CHash{

public:
    CHash(){
        for( int i = 0; i < 500 ;i++){
            holder[i] = NULL;
        }
        first = NULL;
        last  = NULL;
    };
    void insert( string key , string value ){
        size_t num = index(key);
        Node *tmp;
        if( holder[num] == NULL ){
            tmp = new Node(key , value , NULL);
            holder[num] = tmp;
        }else{
            tmp = new Node(key, value , holder[num]);
            holder[num] = tmp;
        }
        if( first == NULL){
            tmp -> nextNode = NULL;
            tmp -> prevNode = NULL;
            first = tmp;
            last  = tmp;
        }else{
            tmp -> prevNode = last;
            last -> nextNode = tmp;
            last = tmp;
        }
    }
    void Print( size_t number ){
        Node *tmp = holder[number];
        while( tmp!= NULL){
            cout << tmp -> value << endl;
            tmp = tmp -> next;
        }
    }
    void PrintAll(){
        Node *tmp = first;
        while( tmp != NULL){
            cout << tmp -> value << endl;
            tmp = tmp -> nextNode;
        }
    }
    size_t index( string name ){
        return name.length();
    }
    void de(string val){
        size_t num = index(val);
        if( holder[num] == NULL){
            return;
        }
         Node *tmp = holder[num];
         Node *help;
         Node *help1;
        while( tmp != NULL){
            if( tmp -> key == val){
                Node *temp = tmp;
                if( tmp -> prevNode != NULL)
                    help = tmp -> prevNode;
                else
                          help = NULL;
                if( tmp -> nextNode != NULL)
                    help1 = tmp -> nextNode;
                else
                          help1 = NULL;
                if( tmp -> next != NULL){
                    tmp = tmp -> next;
                    tmp -> nextNode = help1;
                    tmp -> prevNode = help;
                }
                else
                    tmp = NULL;

                delete temp;
                return ;
            }
            tmp = tmp -> next;
        }
    }

它有效,让我感到困扰的是de方法。它应该找到具有与参数相同的键的节点并将其删除。此删除应反映在两个链表中。我一直试图解决这个问题,但它总是会引发seg错误。

使用示例。

 CHash one;
    one.insert("two","cauko");
    one.insert("tuk","hello");
    one.insert("three","hrello");
    one.Print(3) // should print "hello" , "cauko"
    one.PrintAll() // should print "cauko" , "hello" , "hrello"
    one.de("tuk");
    one.Print(3); // should print only "cauko"
    one.PrintAll(); // should print "cauko" , "hrello"

我在哪里弄错了?

3 个答案:

答案 0 :(得分:3)

您应该为de函数指定一个更明确的名称,添加注释,为单个任务创建更多函数,例如查找特定值的节点并提供完全可编译的代码。

de下面的代码假设使用->next的链接列表没有相应的prev,因为没有关于此主题的信息。

void deleteVal(string val){
    size_t num = index(val);
    if( holder[num] == NULL){
        return;
    }

    /* Find the key first */
    Node* tmp = holder[num];
    Node *prev = NULL;
    while (tmp != NULL) {
        if (tmp->key == val) {
            break;
        }
        prev = tmp;
        tmp = tmp->next;
    }

    if (tmp->key != val) {
        //key not found
        return;
    }

    /* remove the element from the global linked list */
    if (tmp->prevNode) {
        tmp->prevNode->nextNode = tmp->nextNode;
    }
    if (tmp->nextNode) {
        tmp->nextNode->prevNode = tmp->prevNode;
    }

    if (first == tmp) {
        first = tmp->nextNode;
    }
    if (last == tmp) {
        last = tmp->prevNode;
    }

    /* Now remove the element from the linked list corresponding to index */
    if (holder[num] == tmp) {
        holder[num] = tmp->next;
    } else {
        prev->next = tmp->next;
    }
//uncomment if the ->prev member exists in your class
//     if (tmp->next) tmp->next->prev = tmp->prev;
    /* Delete. */
    delete tmp; //maybe tmp->next = tmp->nextNode = NULL before depending on your destructor
}

主要问题是您在代码中混合了两个链接列表:

            if( tmp -> next != NULL){
                tmp = tmp -> next;
                tmp -> nextNode = help1;
                tmp -> prevNode = help;
            }

这两个链接列表彼此无关。

答案 1 :(得分:1)

  

我有一个链表数组,每个数组索引都包含链表。

     

除此之外,我还有另一个链接列表,它按照我输入的确切顺序保存节点。

您不应该在这些链接列表之间共享节点,除非您使用

之类的内容
struct Node {
    // ...
    std::shared_ptr<Node> prev_node;
    std::shared_ptr<Node> next_node;
};

另请查看What is the Rule of Three

答案 2 :(得分:1)

您正在尝试管理两个交织在一起的链接列表,而您正在将它们两者都粉碎。 在尝试这种复杂的事情之前,你必须掌握更简单的练习。

具体来说,问题在于:

if( tmp -> next != NULL){
  tmp = tmp -> next;
  tmp -> nextNode = help1;
  tmp -> prevNode = help;
}
else
tmp = NULL;

您完全忽略了next指向tmp的节点。而不是通过helphelp1(您的变量名称是可怕的)将两个节点相互连接,而是将它们连接到无关节点