zoukankan      html  css  js  c++  java
  • 双向链表(链表)

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

     继承关系图:

     

     实体图:

     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

    扩展继承图:

  • 相关阅读:
    css学习笔记1
    HTML学习笔记4
    Layui使用入门教程
    MVC _Layout
    C# MVC _viewstart.cshtml的作用
    用javascript提交表单
    form表单中的属性和标签
    <input>标签中id和name的作用和区别
    input type = button 的onclick属性调用函数
    form表单提交onclick和onsubmit
  • 原文地址:https://www.cnblogs.com/zsy12138/p/11067822.html
Copyright © 2011-2022 走看看