创建有序链表时缺少节点?

时间:2016-01-23 22:22:49

标签: c++ data-structures doubly-linked-list

我试图通过遍历其节点并通过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); }

class UserSignupType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('userType', ChoiceType::class, array(
                'choices' => array(
                    "Subscriber" => "Subscriber",
                    "Friend" => "Friend"
                    ),
                'expanded' => true,
                'mapped' => false
                ));

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) {
                $form = $event->getForm();

                $usertype = $form->get('userType')->getData(); //updated per JBaffords answer

                if($userType == "Subscriber")
                {
                    $builder->add('agency', EntityType::class, array(
                        "class" => "\AppBundle\Entity\Agency",
                        "label" => "name"));
                }
                elseif($userType == "Friend")
                {
                    $builder->add('phoneNumber', PhoneNumberType::class, array(
                        'default_region' => 'US',
                        'format' => PhoneNumberFormat::NATIONAL));
                }
            }
        );
    }

    // ...
}

订购后的输出:

  

[宙斯
  赫拉
  雅典娜]

预期产出:

  

[宙斯
  海神
  赫拉
  雅典娜
  战神]

Live Example

1 个答案:

答案 0 :(得分: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;
}

然后它应该工作:live demo