Data Structure BASICS (11) and data structure basics 11

Source: Internet
Author: User

Data Structure BASICS (11) and data structure basics 11

Cyclic linked list: the pointer of the pointer field of the last node refers to the linked list of the first node;

The difference between a cyclic single-chain table and a single-chain table is that the pointer to the most node in the table is no longer NULL, but instead directed to the header node (so we need to slightly modify our original MyList ), the entire linked list forms a ring.

Therefore, the null condition of the cyclic single-chain table is no longer whether the pointer of the header node is null, but whether it is equal to the header node;

In fact, if you simply implement a circular linked list to improve the performance of a single-chain table, but it increases the complexity of code implementation, but if it is combined with the two-way linked list in the next article, the speed improvement is amazing. Therefore, this blog is a transitional process. It plays a crucial role in connecting the previous blog with the next blog.

 

Below is MyList. h's complete code and analysis, due to the large amount of code, hope to be able to read carefully, but in fact, most of the following code is similar to the previous one, but only a few of them are slightly modified, when it comes to differences from a single-chain table, I will comment out with the ++ symbol:

# Ifndef MYLIST_H_INCLUDED # define MYLIST_H_INCLUDED # include <iostream> # include <stdexcept> using namespace std; // circular linked list // declare template <typename Type> class MyList; template <typename Type> class ListIterator; // linked list Node template <typename Type> class Node {// you can use the MyList class as the Node's friend element. // you can also make the Node class A nested class of MyList, nested in MyList, you can also complete this function: friend class MyList <Type>; friend class ListIterator <Type>; template <typename T> friend Ostream & operator <(ostream & OS, const MyList <T> & list); private: // constructor Description: // next = NULL; // because this is a newly generated Node, the next Node is empty Node (const Type & dataValue): data (dataValue), next (NULL) {} Type data; // data field: Node data Node * next; // pointer field: next Node }; // linked list template <typename Type> class MyList {template <typename T> friend ostream & operator <(ostream & OS, const MyList <T> & list ); friend class ListIterator <Type>; public: My List ();~ MyList (); // Insert the element into the header void insertFront (const Type & data); // Insert the element to the Position index (index starts from 1) void insert (const Type & data, int index); // Delete the node void remove (const Type & data); bool isEmpty () const; private: // The pointer to the first Node: Node <Type> * first ;}; template <typename Type> MyList <Type >:: MyList () {// first points to an empty Node first = new Node <Type> (0); // ++ this is a key point. // The next element of first points to first // at this time, indicates whether or not the chain table has reached the end. The result is no longer (whether it is equal to NULL) // Change to (whether it is equal to first) // because first represents the last element of the linked list // At the same time, first is the first element of the first element first-> next = first;} template <typename Type> MyList <Type> ::~ MyList () {Node <Type> * deleteNode = NULL; // ++ Save the Node <Type> * tmp = first; // ++ first points to the first real element first = first-> next; // all the way to the end of the linked list while (first! = Tmp) {deleteNode = first; first = first-> next; delete deleteNode;} // ++ release to the empty node delete tmp of the linked list ;} // this step is the same as the previous linked list template <typename Type> void MyList <Type >:: insertFront (const Type & data) {Node <Type> * newNode = new Node <Type> (data); newNode-> next = first-> next; first-> next = newNode ;} template <typename Type> void MyList <Type>: insert (const Type & data, int index) {// because we have added an empty node to the header, // If the linked list is empty, or Add an element at the position where the linked list is 1 // its operation is the same as adding an element at other locations int count = 1; // at this time, searchNode is definitely not the first Node <Type> * searchNode = first; // ++ note: modify NULL to first // locate the position to be inserted // If the given index is too large (beyond the length of the linked list) // Insert the element to the end of the linked list table. // The cause is searchNode-> next! = First, this condition does not meet the while (count <index & searchNode-> next! = First) {++ count; searchNode = searchNode-> next;} // Insert the linked list Node <Type> * newNode = new Node <Type> (data ); newNode-> next = searchNode-> next; searchNode-> next = newNode;} template <typename Type> void MyList <Type >:: remove (const Type & data) {if (isEmpty () return; Node <Type> * previous = first; // Save the previous Node for (Node <Type> * searchNode = first-> next; // searchNode! = NULL; // ++ note that it is no longer used to determine whether the searchNode is NULL! = First; // ++, but not equal to first. first represents searchNode = searchNode-> next) at the end of the linked list {if (searchNode-> data = data) {previous-> next = searchNode-> next; delete searchNode; // re-adjust the searchNode pointer // check whether there are any equal elements in the traversal chain table // ++ note // if the current searchNode has reached the last node // that is, searchNode-> next already equal to first, the following statement cannot execute if (previous-> next = first) break; searchNode = previous-> next;} previous = searchNode ;}} // note the empty condition template <typename Ty Pe> bool MyList <Type >:: isEmpty () const {return first-> next = first;} // display all data in the Linked List (for testing) template <typename Type> ostream & operator <(ostream & OS, const MyList <Type> & list) {for (Node <Type> * searchNode = list. first-> next; searchNode! = List. first; // ++ Note: searchNode = searchNode-> next) {OS <searchNode-> data; if (searchNode-> next! = List. first) // ++ note (not reaching the end of the linked list) cout <"->";} return OS;} // in addition to the condition for determining null OF THE ListIterator function, no template <typename Type> class ListIterator {public: ListIterator (const MyList <Type> & _ list): list (_ list), currentNode (_ list. first)-> next) {}// reload * operator const Type & operator * () const throw (std: out_of_range); Type & operator * () throw (std :: out_of_range); // overload-> operator const Node <Type> * operator-> () const throw (std: out_of_range); Node <Type> * operator-> () throw (std: out_of_range); // overload ++ operator ListIterator & operator ++ () throw (std: out_of_range); // Note: The returned value is, instead of reference ListIterator operator ++ (int) throw (std: out_of_range); bool isEmpty () const; private: const MyList <Type> & list; node <Type> * currentNode;}; template <typename Type> bool ListIterator <Type>: isEmpty () const {// + note: the empty condition is changed to list. first if (currentNode = list. first) return true; return false;} 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"); // return the content pointed to by the current pointer return currentNode-> data ;} template <typename Type> Type & ListIterator <Type>: operator * () throw (std: out_of_range) {// first add the const attribute for * this, // to call the const version of the function, // then use const_case, // convert the const attribute included in the function call to the/operator-> () the non-const version of is the same as the return const_cast <Type &> (static_cast <const ListIterator <Type >&> (* this ). operator * ();} template <typename Type> const Node <Type> * ListIterator <Type>: operator-> () constthrow (std: out_of_range) {if (isEmpty () throw std: out_of_range ("iterator is out of range"); // directly return the pointer return currentNode ;} template <typename Type> Node <Type> * ListIterator <Type>: operator-> () throw (std: out_of_range) {// see return const_cast <Node <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"); // the pointer moves forward currentNode = currentNode-> next; return * this ;} template <typename Type> ListIterator <Type>: operator ++ (int) throw (std: out_of_range) {ListIterator tmp (* this ); ++ (* this); // call the forward ++ version return tmp;} # endif // MYLIST_H_INCLUDED

Appendix-test code:

int main(){    MyList<int> iMyList;    for (int i = 0; i < 10; ++i)    //1 2 3 4 5 6 7 8 9 10        iMyList.insert(i+1, i+1);    for (int i = 0; i < 5; ++i)     //40 30 20 10 0 1 2 3 4 5 6 7 8 9 10        iMyList.insertFront(i*10);    iMyList.insertFront(100);//100 40 30 20 10 0 1 2 3 4 5 6 7 8 9 10    iMyList.remove(10);      //100 40 30 20 0 1 2 3 4 5 6 7 8 9    iMyList.remove(8);       //100 40 30 20 0 1 2 3 4 5 6 7 9    cout << "------------ MyList ------------" << endl;    for (ListIterator<int> iter(iMyList);            !(iter.isEmpty());            ++ iter)        cout << *iter << ' ';    cout << endl;    cout << "Test: \n\t" << iMyList << endl;    return 0;}

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.