Data Structure Foundation (12)--design and implementation of two-way cyclic chain list

Source: Internet
Author: User

The operating characteristics of the doubly linked list:

(1) "inquiry" and the same as the single linked list;

(2) "Insert" and "delete" need to modify the pointer in two directions at the same time.

However, for a two-way loop, the list is inserted very quickly at the end of the table, with an O (1) time, because there is a pointer to the front, so the two-way loop list is easy to find the element at the end of the table, so the two-way circular list comparison is suitable for frequent insertion at the end of the case.



Empty linked list:


Two-way cyclic linked list node construction:

Class Doublelistnode{private:    Type data;    Doublelistnode *prev;   Forward pointer field    Doublelistnode *next;   latter pointer field};

Because it needs to be used for the doublelist class , it needs to be transformed as follows :

Template <typename type>class doublelistnode{    //friend declaration    friend Class doublelist<type>;    Friend Class listiterator<type>;    Template <typename t>    friend Ostream &operator<< (ostream &os, const doublelist<t> & List);p rivate:    doublelistnode (const Type &datavalue)        :d ata (datavalue), prev (null), Next (null) {}    Type data;    Doublelistnode *prev;   Forward pointer field    Doublelistnode *next;   latter pointer field};

Two-way cyclic linked list construction :

Template <typename type>class doublelist{    friend class listiterator<type>;    Template <typename t>    friend Ostream &operator<< (ostream &os, const doublelist<t> & List);p ublic:    doublelist ();    ~doublelist ();    void push_back (const Type &data);    void Push_front (const Type &data);    void Insert (int position, const Type &data);    void Pop_front ();    void Pop_back ();    void Remove (const Type &removedata);    BOOL Search (const Type &searchdata) const;    BOOL IsEmpty () const    {        return (First->next = = first);    } Private:    //Insert node X into node previous after    void Insertprivate (doublelistnode<type> *previous,                       Doublelistnode<type> *x);    void Removeprivate (doublelistnode<type> *x);p rivate:    doublelistnode<type> *first;};

construction and destruction of linked list :

Construct the list template <typename type>doublelist<type>::D oublelist () {First    = new Doublelistnode<type > (0);    First->next = First;    First->prev = First;}
destructor list template <typename type>doublelist<type>::~doublelist () {    doublelistnode<type> * Deletenode = NULL;    Save chain footer Element    doublelistnode<type> *tmp = first;    First it points first to the real element, firstly    = first->next;    All the way to the end of the list    while (first! = tmp)    {        deletenode = first;        First = next;        Delete deletenode;    }    Releases the empty node (header) of the linked list    delete tmp;

Two main forces for inserting and deleting linked list elements :

Same as Private member//Insert node template <typename type>void doublelist<type>::insertprivate (doublelistnode< Type> *previous,                                     doublelistnode<type> *x) {    X->prev = previous;    X->next = previous->next;    Previous->next->prev = x;    Previous->next = x;}

Delete node template <typename type>void doublelist<type>::removeprivate (doublelistnode<type> *x) {    if (x = = first)        throw Std::range_error ("Permission denied to delete first pointer");    X->prev->next = x->next;    X->next->prev = x->prev;    Delete x;}

Insert for customer :

Insert to Footer template <typename type>void doublelist<type>::p ush_back (const Type &data) {Doublelistnode    <Type> *newnode = new doublelistnode<type> (data);    Find the previous node of first doublelistnode<type> *previous = first->prev; Insert Insertprivate (Previous, newNode);} Insert into table header template <typename type>void doublelist<type>::p ush_front (const Type &data) {Doublelistnode    <Type> *newnode = new doublelistnode<type> (data); Inserted after first insertprivate (first, newNode);} Insert to any position (specified by position) template <typename type>void doublelist<type>::insert (int position, const TYPE    &data) {if (position = = 1) return Push_front (data);    int count = 1;    Previous represents a position before the insertion position doublelistnode<type> *previous = first->next;    If the position is too large, then previous find first will stop//the element should be inserted at the end of the list while (Count < position-1 && Previous! = first)        {+ + count;    Previous = previous->next;}//If the end of the linked list is found or if the linked list is empty at this time, insert to footer if (previous = = first) return push_back (data);    If a suitable insertion position is found doublelistnode<type> *newnode = new doublelistnode<type> (data); Insertprivate (Previous, newNode);}

Delete provided to the customer :

Delete Footer element template <typename type>void doublelist<type>::p op_back () {    removeprivate (first->prev);} Delete Table header element template <typename type>void doublelist<type>::p Op_front () {    removeprivate (first->next) ;} Delete all elements of element value Removedata template <typename type>void doublelist<type>::remove (const Type &removedata {    if (IsEmpty ())        throw std::range_error ("link list is empty");    for (doublelistnode<type> *searchnode = first->next;            Searchnode! = First;            Searchnode = Searchnode->next)    {        if (Searchnode->data = = removedata)            removeprivate (Searchnode) ;    }}

To see if it exists in the linked list :

Template <typename type>bool doublelist<type>::search (const Type &searchdata) const{    doublelistnode<type> *searchnode = first->next;    while (searchnode! = first)    {        if (Searchnode->data = = Searchdata)            return true;        Searchnode = searchnode->next;    }    return false;}

All elements of the output list ( for testing purposes ):

Template <typename type>ostream &operator<< (ostream &os, const doublelist<type> &list) { For    (doublelistnode<type> *currentnode = (list.first)->next;            CurrentNode! = List.first;            CurrentNode = currentnode->next)        os << currentnode->data << ";    return OS;}

design and implementation of bidirectional loop-linked list iterator :
In addition to adding operator--, hardly made any changes to the template <typename type>class listiterator{public:listiterator (const doublelist <Type> &_list): List (_list), CurrentNode ((_list.first)->next) {}//reload *operator const TYP    e &operator* () const throw (Std::out_of_range);    Type &operator* () throw (Std::out_of_range);    Overload->operator Const doublelistnode<type> *operator-> () const throw (Std::out_of_range);    Doublelistnode<type> *operator-> () throw (Std::out_of_range);    Overload ++operator Listiterator &operator++ () throw (Std::out_of_range);    Note: The value returned here is not reference listiterator operator++ (int) throw (std::out_of_range);    Overload--operator,//actually this version of the--operator is imperfect,//because he did not make any mistakes in controlling listiterator &operator--();    Note: The value returned here is not reference listiterator operator--(int);    BOOL IsEmpty () const {return (CurrentNode = = List.first);    }private:const doublelist<type> &list; DoublelistNode<type> *currentnode;}; 
template <typename type>const Type &listiterator<type>::operator* () Constthrow (Std::out_of_range) {if (    IsEmpty ()) Throw Std::out_of_range ("iterator is out of range"); Returns the content pointed to by the current pointer return currentnode->data; Template <typename Type>type &listiterator<type>::operator* () throw (Std::out_of_range) {return C        Onst_cast<type &> (static_cast<const listiterator<type> &> (*this). operator* () );}
template <typename type>const doublelistnode<type> *listiterator<type>::operator-> () Constthrow (std::o    Ut_of_range) {if (IsEmpty ()) Throw Std::out_of_range ("iterator is out of range"); Return directly to the pointer return currentnode;} Template <typename type>doublelistnode<type> *listiterator<type>::operator-> () throw (std::out _of_range) {return const_cast<doublelistnode<type> *> (Static_cast<const listiterator <Type> > (*this) .operator-> ());} 
template <typename type>listiterator<type> &listiterator<type>::operator++ () throw (std::out_of_range    {if (IsEmpty ()) Throw Std::out_of_range ("iterator is out of range");    Pointer move forward CurrentNode = currentnode->next; return *this;} Template <typename type>listiterator<type> listiterator<type>::operator++ (int) throw (std::out_of    _range) {listiterator tmp (*this); + + (*this); Call the previous + + version of return tmp;} 
Template <typename type>listiterator<type> &listiterator<type>::operator--() {    //pointer move forward    CurrentNode = currentnode->prev;    return *this;} Template <typename type>listiterator<type> listiterator<type>::operator--(int) {    listiterator<type> tmp (*this);    --(*this);    return TMP;}

Test Code :

int main () {cout << "--------1--------" << Endl;    Doublelist<int> myList;    for (int i = 0; i < 3; ++i) Mylist.push_back (i+1);    for (int i = 0; i < 5; ++i) Mylist.push_front (10+i);    for (int i = 0; i < 3; ++i) Mylist.push_back (i+1);    Listiterator<int> iter (myList), Iter2 (myList);        while (!iter.isempty ()) {cout << *iter << ";        + + iter;    + + Iter2;    } cout << Endl;    --Iter2;        while (!iter2.isempty ()) {cout << *iter2 << ";    Iter2--;    } cout << Endl;    cout << "--------2--------" << Endl;    cout << myList << Endl;    cout << "Test insert ..." << Endl;    Mylist.insert (1, 14);    Mylist.insert (2, 13);    Mylist.insert (2, 13);    Mylist.insert (88, 88);    cout << myList << Endl;    Mylist.pop_back ();    Mylist.pop_front ();    cout << myList << Endl; for (int i = 0; I < 5;        ++i) {if (Mylist.search (i)) cout << i << ": Have found!" << Endl;    else cout << i << ": Not in the list!" << Endl;    } cout << "Test remove ..." << Endl;    cout << myList << Endl;    int value;        while (Cin >> value) {try {mylist.remove (value);        } catch (const std::exception &e) {cerr << e.what () << Endl;        } cout << myList << Endl;        if (Mylist.isempty ()) {cout << "empty" << Endl;        } else {cout << "not empty" << Endl; }} return 0;}

Data Structure Foundation (12)--design and implementation of two-way cyclic chain list

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.