线性表的正向迭代器实现

线性表包括 : 数组(动态数组类,静态数组类), 链表, 栈, 队列

以双向链表为例, 实现正向迭代器.


测试程序

// testcase.cpp : Defines the entry point for the console application.
//

#include <stdlib.h>
#include <stdio.h>

#include "LsDoublyLinkedList.h"

void fnTestDbList(); ///< 测试CLsLinkedList<T>双链表的所有接口

int main(int argc, char* argv[])
{
    fnTestDbList();
    return 0;
}

void fnTestDbList()
{
    int i = 0;
    int iTmp = 0;
    CLsLinkedList<int> list;
    CLsLinkedList<int>::iterator it = NULL;
    CLsLinkedList<int>::iterator itToDel = NULL;
    
    for (i = 1; i < 10; i++)
    {
        it = list.addTail(i);
        list.setAt(it, 100 + i);
        iTmp = list.getAt(it);   
        
        it = list.addHead(i + 200);
        list.setAt(it, 100 + i);
        iTmp = list.getAt(it);
        
        if (0 == (i % 2))
        {
            itToDel = it;
            list.insert(it, 300 + i);
        }
    }
    
    list.removeAt(itToDel);
    list.removeHead();
    list.removeTail();
    
    printf("[%d]\n", list.getLength());
    it = list.getHead();
    while (it != list.end())
    {
        printf("%d ", *it);
        it++;
    }
    
    printf("\r\n");
    it = list.getTail();
    while(it != list.end())
    {
        printf("%d ", *it);
        it++;
    }
    
    printf("\r\n");
 }

带正向迭代器的双向链表实现

// LsDoublyLinkedList.h: interface for the CLsLinkedList class.
//
//

#if !defined(LSDOUBLYLINKEDLIST_H_82FEA8FE_F7B8_4CD7_A162_751580726632)
#define LSDOUBLYLINKEDLIST_H_82FEA8FE_F7B8_4CD7_A162_751580726632

/**
链表总结
空间
    链式存储
时间复杂度
    尽量避免提供非常量阶的接口
    增加操作: O(1) 常量阶, 快
    删除操作: O(1) 常量阶, 快
    修改操作:O(1) 快(条件:知道位置, 用的是先前返回的位置类或结点指针)
    查询操作:O(n) 线性阶, 慢
    随机访问:O(n) 线性阶, 慢
使用场合
    * 问题规模不确定
    * 随机访问频率低
    * 数据更新频率高(主要指的是添加和删除操作)
缺点
    * 查询速度慢(数组和链表查询速度都慢)
原生new的时间复杂度
    new实现是线性阶.
    调用的memset是线性阶, 有循环操作.
    HeapAlloc中没源码, 但是有循环操作, 是线性阶.
    new不影响时间增长率.

结论
    当算法中, new次数较少时, 可以忽略new对算法时间复杂度的影响.
    当new次数较多时, 可以一次多new几个元素(e.g. 10个), 下次就不用new, 直接取已经new好的数据操作, 等用完了, 才再次new几个元素出来.
    这样对new操作做优化, 等于自己做堆管理, 需要再做一个链表, 将new出来的10个一组的小块内存空间管理起来, 当一个类指针不用了, 就称为闲置空间, 放在内存池中. 下次不用再申请了, 可以复用.
    等链表析构时, 链表的原生操作完成后, 再一块释放内存池.
*/

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/// ----------------------------------------------------------------------
/// CLsLinkedList 双链表 定义
/// ----------------------------------------------------------------------
template <typename T>
class CLsLinkedList  
{
public:
    /// ----------------------------------------------------------------------
    /// CLsLinkedNode 定义
    /// ----------------------------------------------------------------------
    
    /// LsDoublyLinkedList's Node
    template <typename T>
        struct CLsLinkedNode
    {
        friend CLsLinkedList<T>; ///< 不需要前向声明, 用到的时候才检查
        friend CLsLinkedList<T>::iterator;

    private:
        CLsLinkedNode(T Elem)
            :m_Elem(Elem)
            ,m_pNext(NULL)
            ,m_pPrev(NULL)
        {
        }
        
        ~CLsLinkedNode()
        {
        }

        T m_Elem; //数据元素
        CLsLinkedNode<T>* m_pPrev; //前驱
        CLsLinkedNode<T>* m_pNext; //后继
    };

    /// ----------------------------------------------------------------------
    /// 正向迭代器 定义
    /// ----------------------------------------------------------------------
    class iterator
    {
        friend class CLsLinkedList<T>;
    public:
        iterator()
        {
            m_pNode = NULL;
        }

        iterator(CLsLinkedNode<T>* pNode)
        {
            m_pNode = pNode;
        }
        
        iterator operator++()
        {
            m_pNode = m_pNode->m_pNext;
            return m_pNode;
        }
        
        iterator operator++(int)
        {
            CLsLinkedNode<T> *pTemp = m_pNode;
            m_pNode = m_pNode->m_pNext;
            return pTemp;
        }

        iterator operator--()
        {
            m_pNode = m_pNode->m_pPrev;
            return m_pNode;
        }
        
        iterator operator--(int)
        {
            CLsLinkedNode<T> *pTemp = m_pNode;
            m_pNode = m_pNode->m_pPrev;
            return pTemp;
        }
        
        T& operator* ()
        {
            return m_pNode->m_Elem;
        }
        
        bool operator!= (const iterator& obj)
        {
            return m_pNode != obj.m_pNode;
        }

        bool operator== (const iterator& obj)
        {
            return m_pNode == obj.m_pNode;
        }

    private:
        CLsLinkedNode<T>* GetNode()
        {
            return m_pNode;
        }

    private:
        CLsLinkedNode<T>* m_pNode;
    };

public:
    iterator begin()
    {
        return m_pHead;
    }

    iterator end()
    {
        return NULL;
    }

public:
    CLsLinkedList();
    virtual ~CLsLinkedList();

    /// 只提供O(1)的接口^_^

    iterator getTail() const;
    iterator getHead() const;
    inline bool isEmpty() const;
    inline size_t getLength() const;  //表长
    void clear();

    iterator addTail(T newElem);
    bool removeTail();

    iterator addHead(T newElem);
    bool removeHead();

    T getAt(iterator it) const;
    void setAt(iterator it, T newElem);
    bool removeAt(iterator it);

    bool insert(iterator it, T newElem);

private:
    CLsLinkedNode<T>* m_pHead;  //头结点
    CLsLinkedNode<T>* m_pTail;  //尾结点
    size_t m_nLength;
};

/// ----------------------------------------------------------------------
/// CLsLinkedList 实现
/// ----------------------------------------------------------------------
template <typename T>
inline size_t CLsLinkedList<T>::getLength() const
{
    return m_nLength;
}

template <typename T>
inline bool  CLsLinkedList<T>::isEmpty() const
{
    return (NULL == m_pHead) ? true : false;
}

template <typename T>
CLsLinkedList<T>::CLsLinkedList()
:m_pHead(NULL)
,m_pTail(NULL)
,m_nLength(0)
{
}

template <typename T>
CLsLinkedList<T>::~CLsLinkedList()
{
    clear();
}

template <typename T>
void CLsLinkedList<T>::clear()
{
    while (!isEmpty())
    {
        removeTail();
    }
}

template <typename T>
T CLsLinkedList<T>::getAt(CLsLinkedList::iterator it) const
{
    return *it;
}

template <typename T>
void CLsLinkedList<T>::setAt(CLsLinkedList::iterator it, T newElem)
{
    *it = newElem;
}

template <typename T>
bool CLsLinkedList<T>::insert(CLsLinkedList::iterator it, T newElem)
{
    CLsLinkedNode<T>* pNewNode = NULL;
    CLsLinkedNode<T>* pPrev = NULL;
    CLsLinkedNode<T>* pNext = NULL;

    pPrev = it.GetNode();
    if (NULL == pPrev)
    {
        return false;
    }

    pNewNode = new CLsLinkedNode<T>(newElem);
    pNext = pPrev->m_pNext;
    
    /*
    1 2 3 [6] 4 5
    3.next = 6
    4.prev = 6
    6.prev = 3
    6.next = 4
    
      1 2 3 4 5 [6]
    */
    pPrev->m_pNext = pNewNode;
    if (NULL != pNext)
    {
        pNext->m_pPrev = pNewNode;
    }

    pNewNode->m_pPrev = pPrev;
    pNewNode->m_pNext = pNext;
    m_nLength++;
    return true;
}

template <typename T>
bool CLsLinkedList<T>::removeTail()
{
    bool bRc = false;
    CLsLinkedNode<T>* pPrev = NULL;

    if (NULL == m_pHead)
    {
        return false;
    }
    
    //1 2 [3]
    if (NULL != m_pTail)
    {
        pPrev = m_pTail->m_pPrev;
        if (NULL != pPrev)
        {
            pPrev->m_pNext = NULL;
        }
        else
        {
            m_pHead = NULL;
        }
        
        delete m_pTail;
        bRc = true;
        m_pTail = pPrev;
        m_nLength--;
    }

    return bRc;
}

template <typename T>
bool CLsLinkedList<T>::removeHead()
{
    if (NULL == m_pHead)
    {
        return false;
    }
    
    //[1] 2 3
    CLsLinkedNode<T>* pNext = m_pHead->m_pNext;
    if (NULL != pNext)
    {
        pNext->m_pPrev = NULL;
    }
    else
    {
        m_pTail = NULL;
    }
    
    delete m_pHead;
    m_nLength--;
    m_pHead = pNext;
    return true;
}

template <typename T>
bool CLsLinkedList<T>::removeAt(CLsLinkedList::iterator it)
{
    CLsLinkedNode<T>* pDelNode = it.GetNode();
    CLsLinkedNode<T>* pPrev = NULL;
    CLsLinkedNode<T>* pNext = NULL;

    if ((NULL == m_pHead) 
        || (NULL == pDelNode))
    {
        return false;
    }
    
    /*
    1 2 [3] 4 5 
    2.next = 4
    4.prev = 2
    
      [1] 2 3 4 5 
      
        1 2 3 4 [5]
        
          [1]
    */
    pPrev = pDelNode->m_pPrev;
    pNext = pDelNode->m_pNext;

    if (NULL != pPrev)
    {
        pPrev->m_pNext = pNext;
    }
    else
    {
        m_pHead = pNext;
    }
    
    if (NULL != pNext)
    {
        pNext->m_pPrev = pPrev;
    }
    else
    {
        m_pTail = pPrev;
    }
    
    delete pDelNode;
    m_nLength--;
    
    return true;
}

template <typename T>
CLsLinkedList<T>::iterator CLsLinkedList<T>::addTail(T newElem)
{
    CLsLinkedList<T>::CLsLinkedNode<T>* pNewNode = new CLsLinkedList<T>::CLsLinkedNode<T>(newElem);
    
    //空表
    if (NULL == m_pHead)
    {
        m_pHead = m_pTail = pNewNode;
    }
    else 
    {
        //1 2 3 4 5 [6]
        //5.next = 6    6.prev = 5  tail = 6
        m_pTail->m_pNext = pNewNode;
        pNewNode->m_pPrev = m_pTail;
        m_pTail = pNewNode;
    }

    m_nLength++;

    return pNewNode;
}

template <typename T>
CLsLinkedList<T>::iterator CLsLinkedList<T>::addHead(T newElem)
{
    CLsLinkedList<T>::CLsLinkedNode<T> *pNewNode = new CLsLinkedList<T>::CLsLinkedNode<T>(newElem);
    
    //空表
    if (NULL == m_pHead)
    {
        m_pHead = m_pTail = pNewNode;
    }
    else 
    {
        //[6] 1 2 3 4 5 
        //1.prev = 6    6.next = 1  head = 6
        m_pHead->m_pPrev = pNewNode;
        pNewNode->m_pNext = m_pHead;
        m_pHead = pNewNode;
    }

    m_nLength++;
    return pNewNode;
}

template <typename T>
CLsLinkedList<T>::iterator CLsLinkedList<T>::getTail() const
{
    return m_pTail;
}

template <typename T>
CLsLinkedList<T>::iterator CLsLinkedList<T>::getHead() const
{
    return m_pHead;
}

#endif // !defined(LSDOUBLYLINKEDLIST_H_82FEA8FE_F7B8_4CD7_A162_751580726632)





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值