数据结构 第30课 双向链表的实现------------------狄泰软件学院

文章目录

引用文章: 1

引用文章: 2

DualLinkList.h

#ifndef DUALLINKLIST_H
#define DUALLINKLIST_H


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

namespace DTLib
{
    
    

template < typename T >
class DualLinkList : public List<T>
{
    
    
    struct Node : public Object
    {
    
    
        T value;
        Node* next;
        Node* pre;
    };


    mutable struct : public Object      // 之前有讲过,先自己查找
    {
    
    
        char reserved[sizeof(T)];
        Node* next;
        Node* pre;
    }m_header;


    int m_length;
    int m_step;
    Node* m_current;


    Node* position(int i) const
    {
    
    
        Node* ret = reinterpret_cast<Node*>(&m_header);

        for(int p=0; p<i; p++)
        {
    
    
            ret = ret->next;
        }

        return ret;
    }

    virtual Node* creat()
    {
    
    
        return new Node();
    }


    virtual void destory(Node* pn)
    {
    
    
        delete pn;
    }

public:
    DualLinkList()
    {
    
    
        m_header.next = NULL;
        m_header.pre = NULL;
        m_length = 0;
        m_step = 1;
        m_current = NULL;
    }


    bool insert(const T &e)
    {
    
    
        return insert(m_length, e);
    }


    bool insert(int i, const T& e)
    {
    
    
        bool ret = ((0 <= i) && (i <= m_length));

        if(ret)
        {
    
    
            Node* node = creat();

            if(node != NULL)
            {
    
    
                Node* current = position(i);
                Node* next = current->next;
                node->value = e;

                node->next = next;  // 1
                current->next = node; // 2

                if(current != reinterpret_cast<Node*>(&m_header))
                {
    
    
                    node->pre = current;  // 3
                }
                else
                {
    
    
                    node->pre = NULL;
                }

                if(next != NULL)
                {
    
    
                    next->pre = node; // 4
                }

                m_length++;
            }
            else
            {
    
    
                THROW_EXCEPTION(NoEnoughMemoryException, "No memery to insert new element...");
            }
        }


        return ret;
    }


    bool remove(int i)
    {
    
    
        bool ret = ((0 <= i) && (i < m_length));

        if(ret)
        {
    
    
            Node* current = position(i);
            Node* toDel = current->next;
            Node* next = toDel->next;

            if( m_current == toDel )
            {
    
    
                m_current = next;
            }

            current->next = next;  //1

            if(next != NULL)
            {
    
    
                next->pre = toDel->pre;  // 2
            }

            m_length--;

            destory(toDel);
        }
        return ret;
    }

    bool set(int i, const T& e)
    {
    
    
        bool ret = ((0 <= i) && (i < m_length));

        if(ret)
        {
    
    
            position(i)->next->value = e;
        }

        return ret;
    }


    virtual T get(int i) const
    {
    
    
        T ret;

        if( get(i, ret) )
        {
    
    
            return ret;
        }
        else
        {
    
    
            THROW_EXCEPTION(IndexOutOfBoundsException, "Invalid parameter i to get element ...");
        }

        return ret;
    }


    bool get(int i, T& e) const
    {
    
    
        bool ret = ((0 <= i) && (i < m_length));

        if(ret)
        {
    
    
            e = position(i)->next->value;
        }
        return ret;
    }


    int find(const T& e) const
    {
    
    
        int ret = -1;
        int i = 0;

        Node* node = m_header.next;

        while( node )
        {
    
    
            if( node->value == e )
            {
    
    
                ret = i;
                break;
            }
            else
            {
    
    
                node = node->next;
                i++;
            }
        }
        return ret;
    }



    bool length() const
    {
    
    
        return m_length;
    }

    void clear()
    {
    
    
        while( m_length > 0 )
        {
    
    
            remove(0);
        }
    }


    virtual bool move(int i, int step = 1)
    {
    
    
        bool ret = (0 <= i) && (i < m_length) && (step > 0);

        if(ret)
        {
    
    
            m_current = position(i)->next;
            m_step = step;
        }
        return ret;
    }



    virtual bool end()
    {
    
    
        return (m_current == NULL);
    }


    virtual T current()
    {
    
    
        if( !end() )
        {
    
    
            return m_current->value;
        }
        else
        {
    
    
            THROW_EXCEPTION(InvalidParameterException, "No value at current position ...");
        }
    }


    virtual bool next()
    {
    
    
        int i = 0;

        while((i < m_step) && !end())
        {
    
    
            m_current = m_current->next;
            i++;
        }

        return (i == m_step);
    }


    virtual bool pre()
    {
    
    
        int i = 0;

        while((i < m_step) && !end())
        {
    
    
            m_current = m_current->pre; // 将m_current通过pre指针,指向当前节点的前驱节点
            i++;
        }
        return (i == m_step);
    }


    ~DualLinkList()
    {
    
    
        clear();
    }
};

}




#endif // DUALLINKLIST_H

main.cpp

#include <iostream>
#include "DualLinkList.h"

using namespace std;
using namespace DTLib;



int main()
{
    
    
    /*  测试一:
    DualLinkList<int> dl;

    for(int i = 0; i < 5; i++)
    {
        dl.insert(0, i);
    }


    for(int i = 0; i < dl.length(); i++)   // 时间复杂度 : O(n*n)
    {
        cout << dl.get(i) << endl;
    }


    cout << "begin" << endl;

    for(dl.move(dl.length() - 1); !dl.end(); dl.pre()) // 时间复杂度 : O(n)
    {
        cout << dl.current() << endl;
    }

    cout << "end" << endl;
    */



    DualLinkList<int> dl;

    for(int i = 0; i < 5; i++)
    {
    
    
        dl.insert(0, i);
        dl.insert(0, 5);
    }

    for(dl.move(0); !dl.end(); dl.next())
    {
    
    
        cout << dl.current() << endl;
    }



    cout << "begin" << endl;
    dl.move(dl.length() - 1);  // 游标定位

    // 删除双向链表中的5
    while(!dl.end())
    {
    
    
        if( dl.current() == 5 )
        {
    
    
            cout << dl.current() << endl;

            dl.remove(dl.find(dl.current()));
        }
        else
        {
    
    
            dl.pre();
        }
    }
    cout << "end" << endl;



    for(dl.move(0); !dl.end(); dl.next())
    {
    
    
        cout << dl.current() << endl;
    }


    return 0;
}

在这里插入代码片
在这里插入代码片

猜你喜欢

转载自blog.csdn.net/dashuu/article/details/115427537