双向循环链表(链表)

Posted zsy12138

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向循环链表(链表)相关的知识,希望对你有一定的参考价值。

 双向链表:每个节点包含指向后继节点的指针和指向前驱节点的指针。

 

 继承关系图:

 技术图片

 实体图:

 

 DualLinkList.h

技术图片
/*
*    DualLinkList:    双向链表类模板
*    成员变量:
*            Node:        节点实体
*            m_header:    头节点
*            m_length    链表长度
*            m_step        步进长度
*            m_current    当前节点前一个节点    
*    成员函数:
*            create()    申请一个新节点        
*            destroy()    删除一个新节点
*            
*            DualLinList()        构造函数初始化成员变量
*            insert()            参数判断,申请新节点,寻找节点,插入节点。分四步:
*            remove()            参数判断,寻找节点,删除节点。                              分三步:
*            set()                参数判断,寻找节点,设置节点值
*            get()                参数判断,寻找节点,获取节点值
*            length()             获取链表长度
*            clean()                释放所有节点空间
*            find()              返回对应值得节点下标
*            position()             返回下标pos节点的上一个的节点指针
*            ~LinkList()            释放所有节点空间
*
*            bool move()         移动游标到指定位置
*            bool end()            判断游标是否到最后
*            T current()            回去当前游标节点值
*            bool next()            移动步长的节点数
*            bool pre()            移动步长的节点数

*/

#ifndef DUALLINKLIST_H
#define DUALLINKLIST_H

#include"List.h"
#include"Exception.h"

namespace DSL

    template <typename T>
    class DualLinkList : public List<T>
    
        protected:
            struct Node : public TopClass
            
                T value;
                Node* next;
                Node* pre;
            ;

            mutable struct : public TopClass
            
                char reserve[sizeof(T)];
                Node* next;
                Node* pre;
            m_header;

            int m_length;
            int m_step;
            Node* m_current;

            virtual Node* create(const T& value)
            
                Node* node = new Node();
                node->value = value;
                if(node == NULL)
                
                    THROW_EXCEPTION(NotEnoughMemoryException,"error: no enough memory to create node!");
                
                return node;
            

            virtual void destroy(Node* toDel)
            
                delete toDel;
                
        public:
            DualLinkList()
            
                m_length = 0;
                m_step = 1;
                m_current = NULL;
                m_header.next = NULL;
                m_header.pre = NULL;
            

            bool insert(const T& obj)
            
                return insert(m_length,obj);
            
            
            bool insert(int pos, const T& obj)
            
                bool ret = ((0 <= pos) && (pos <= m_length));
                if(ret)
                
                    Node* new_node = create(obj);
                    Node* slider_node = reinterpret_cast<Node*>(&m_header);
                    Node* head_node = reinterpret_cast<Node*>(&m_header);
                    for(int i = 0; i < m_length; i++)
                    
                        slider_node = slider_node->next;                    
                    
                    Node* pre_node = slider_node;
                    Node* next_node = slider_node->next;

                    new_node->next = next_node; // pre节点指向new节点,new节点指向next节点 在任何情况下是安全操作
                    pre_node->next = new_node;
                    if(pre_node == head_node) // 插入链表头部
                    
                        new_node->pre = NULL;
                    
                    if(pre_node != head_node) //插入链表中间
                    
                        new_node->pre = pre_node;
                    
                    if(next_node == NULL)     //插入链表末尾
                    
                        ;
                    
                    if(next_node != NULL)     //插入链表中间
                    
                        next_node->pre = new_node;
                    
                    m_length++;
                
                return ret;
            

            bool remove(int pos)
            
                bool ret = ((pos >= 0) && (pos < m_length));
                if(ret)
                
                    Node* slider_node = reinterpret_cast<Node*>(&m_header);
                    for(int i = 0; i < pos; i++)
                    
                        slider_node = slider_node->next;
                    
                    Node* pre_node = slider_node;
                    Node* toDel =slider_node->next;
                    Node* next_node = toDel->next;
                    Node* head_node = reinterpret_cast<Node*>(&m_header);

                    pre_node->next = next_node;  // pre节点指向next节点 在任何情况下是安全操作
                    if(next_node == NULL) // 删除尾节点
                    
                        ;
                    
                    if(next_node != NULL)  // 删除中间节点和头节点
                    
                        next_node->pre = toDel->pre;
                    
                    m_length--;

                    if(m_current == toDel)  // 游标处理
                    
                        m_current = next_node;
                    
                    destroy(toDel);
                
                return ret;
            

            bool set(int pos, const T& obj)
            
                bool ret = ((0 <= pos) && (pos < m_length));
                if(ret)
                
                    Node* slider_node = reinterpret_cast<Node*>(&m_header);
                    for(int i = 0; i < pos; i++)
                    
                        slider_node = slider_node->next;
                    
                    slider_node->next->value = obj;                    
                
                return ret;
            

            T get(int pos) const
            
                T ret;
                get(pos,ret);
                return ret;
            
            
            bool get(int pos, T& obj) const 
            
                bool ret = ((0 <= pos) && (pos < m_length));
                if(ret)
                
                    Node* slider_node = reinterpret_cast<Node*>(&m_header);
                    for(int i = 0; i < pos; i++)
                    
                        slider_node = slider_node->next;
                    
                    obj = slider_node->next->value;
                
                return ret;
            

            int find(const T& obj) const
            
                int ret = -1;
                Node* head_node = reinterpret_cast<Node*>(&m_header);
                Node* slider_node = head_node->next;
                for(int i = 0; i < m_length; i++)
                
                    if(slider_node->value == obj)
                    
                        ret = i;
                        break;
                    
                    else
                    
                        slider_node = slider_node->next;
                    
                
                return ret;
            

            int length() const
            
                return m_length;
            

            void clean()
            
                while(m_length > 0)
                
                    remove(0);
                
            

            bool move(int pos)
            
                bool ret = ((0 <= pos) && (pos < m_length));
                if(ret)
                
                    Node* slider_node = reinterpret_cast<Node*>(&m_header);
                    for(int i = 0; i < pos; i++)
                    
                        slider_node = slider_node->next;
                    
                    m_current = slider_node->next;
                
                return ret;
            

            bool end()
            
                return (m_current == NULL);
            

            T current()
            
                if(m_current != NULL)
                
                    return m_current->value;
                
                else
                
                    THROW_EXCEPTION(IdexOutOfBoundException,"error: operat a no exit node!");
                
            

            bool next(int step = 1)
            
                bool ret = (step > 0);
                if(ret)
                
                    for(int i = 0; (i < step) && (m_current != NULL); i++)
                    
                        m_current = m_current->next;
                    
                
                return ret;
            

            bool pre(int step = 1)
            
                bool ret = (step > 0);
                if(ret)
                
                    for(int i = 0; (i < step) && (m_current != NULL); i++)
                    
                        m_current = m_current->pre;
                    
                
                return ret;
            
            ~DualLinkList()
            
                clean();
            
    ;


#endif
View Code

 

扩展继承图:

技术图片

 

以上是关于双向循环链表(链表)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构开发:循环链表与双向链表

双向循环链表

双向循环链表

双向循环链表

链表练习:单向循环链表变双向

循环链表和双向链表