创建有序链表时缺少节点

问题描述 投票:0回答:1

我试图通过遍历其节点并通过

add_ordered()
添加它们,从现有的双向链表中创建一个有序的双向链表,但是当我打印有序列表时,缺少几个节点。

list.h

#ifnded LIST_H
#define LIST_H

struct Node {
// data member
    std::string value;
// constructors
    Node (std::string v) : value(v) { }
   Node (const Node& src) : value(src.value) { }
// overloaded operators
    friend std::ostream& operator<< (std::ostream& os, const Node& g);
    friend bool operator< (const Node& lhs, const Node& rhs);
    friend bool operator> (const Node& lhs, const Node& rhs);
};
//====================================================================================
// doubly linkes list accepting any object type as its data member (value)
template<class T>
class Link {
public:
    // public data member
    T value;

    // constructor
    Link<T> (T v, Link<T>* p = 0, Link<T>* s = 0) : value(v), prev(p), succ(s) { }
    // copy constructor
    Link<T> (const Link<T>& l) : value(l.value), prev(l.next()), succ(l.previous()) { }

    // non-modifying members
    Link<T>* next () const { return succ; }
    Link<T>* previous () const { return prev; }

    // modifying members
    Link<T>* insert (Link<T>* n);
    Link<T>* add (Link<T>* n);
    Link<T>* add_ordered (Link<T>* n);
private:
    // private data members
    Link<T>* prev;
    Link<T>* succ;
};
#include "list.cpp"
#endif

list.cpp

std::ostream& operator<<(std::ostream& os, const Node& g) {
    os << g.value ;
    return os;
}

bool operator< (const Node& lhs, const Node& rhs) {
    return lhs.value < rhs.value;
}

bool operator> (const Node& lhs, const Node& rhs) {
    return lhs.value > rhs.value;
}
//=======================================================================================

// It inserts the node passed as a parameter before the node currently pointed to by this.
template<class T>
Link<T>* Link<T>::insert (Link<T>* n) {
    if (!n) return this;
    if (!this) return n;

    n->succ = this;
    n->prev = prev;
    if (prev) prev->succ = n;
    prev = n;

    return n;
}

// It inserts the node passed as a parameter after the node currently pointer to by this.
template<class T>
Link<T>* Link<T>::add (Link<T>* n) {
    if (!n) return this;
    if (!this) return n;

    // n->succ = nullptr;
    n->succ = succ;
    n->prev = this;
    succ = n;

    return n;
}

/*
    It inserts the new node such that
    current node and new node in
    lexicographical order; returns
    pointer to last node.

    First node in ordered list contains the
    lexicographically smaller value.

    It assumes argument is the tail.
*/
template<class T>
Link<T>* Link<T>::add_ordered (Link<T>* n) {
    if (!n) return this;
    if (!this) { std::cout <<"new node first\n"; return n; }

    Link<T>* tail = this;
    if (n->value > tail->value) {
        std::cout <<"new node largest \n";
         add(n); // add after current (last) node
        return n;
    }

    Link<T>* current_node = this;
    while (current_node) {
        if (n->value > current_node->value) {
            std::cout <<"new node spliced \n";
            add(n);
             return tail;
        }
        std::cout <<"advance to head\n";
        current_node = current_node->previous();
    }

    insert(n); // insert before current (first) node
    std::cout << "new node smallest\n";
    return tail;
}

main.cpp

#include <iostream>
#include <string>
#include <list.h>

template<class T>
void create_ordered_list (Link<T>* src, Link<T>*& dest) {
    while (src){
        Link<T> l(src->value, nullptr, nullptr);
        dest = dest->add_ordered(new Link<T>(l));
        src = src->next();
    }
}

template<class T>
void print(Link<T>* n) {
    Link<T>* tail = n;

    if (tail->next()) {
        std::cout <<"[";
        while (tail) {
            std::cout << tail->value;
            if (tail = tail->next()) std::cout <<"\n";
        }
        std::cout <<"]";
    } else if (tail->previous()) {
        std::cout <<"[";
        while (tail) {
            std::cout << tail->value;
            if (tail = tail->previous()) std::cout <<"\n";
        }
        std::cout <<"]";
    }
    getchar();
}
//===============================================================
int main () {
    Link<Node>* head = new Link<Node>(Node("Zeus"));
    head = head->insert(new Link<Node>(Node("Hera")));
    head = head->insert(new Link<Node>(Node("Athena")));
    head = head->insert(new Link<Node>(Node("Ares")));
    head = head->insert(new Link<Node>(Node("Poseidon")));

    print<Node>(head);

    std::cout <<"\nOrdered lists\n";
    Link<Node>* ordered_list = nullptr;
    create_ordered_list(head, ordered_list);
    print(ordered_list);
}

下单后输出:

[宙斯
赫拉
雅典娜]

预期输出:

[宙斯
海神波塞冬
赫拉
雅典娜
阿瑞斯]


实例

c++ data-structures doubly-linked-list
1个回答
1
投票

首先你必须纠正

add()
功能:

template<class T>
Link<T>* Link<T>::add (Link<T>* n) {
    ...
    n->succ = succ;
    n->prev = this;
    succ = n;   
    if (n->succ) n->succ->prev = n; ///!!!

    return n;
}

然后你必须在

add()
函数中颠倒一些
insert()
add_ordered()
并调整一些回报:

template<class T>
Link<T>* Link<T>::add_ordered (Link<T>* n) {
    if (!n) return this;
    if (!this) { std::cout <<"new node first\n"; return n; }

    Link<T>* tail = this; 
    if (n->value > tail->value) {
        std::cout <<"new node largest \n";
        return insert(n); // No: you need to insert before current node !!!
    }

    Link<T>* current_node = this; 
    while (current_node) {
        if (n->value > current_node->value) {
            std::cout <<"new node spliced \n";
            add(n);
            return this;
        }
        std::cout <<"advance to head\n";
        current_node = current_node->previous();
    } 

    add(n); // no: here we have to add at the end !
    std::cout << "new node smallest\n";
    return this;
}

然后它应该可以工作:现场演示

© www.soinside.com 2019 - 2024. All rights reserved.