单线性链表的c++实现

#include <cstdlib>
#include <ctime>
#include <iostream>

namespace LINKLIST
{
    template<typename T> class CLinkList;

    template<class T>
    class CLinkNode
    {
        friend class CLinkList<T>;
    private:
        T			m_data;
        CLinkNode	*m_pNext;
    };

    template<class T>
    class CLinkList
    {
    public:
        // 初始化线性列表
        bool InitList();

        // 初始条件:线性表已存在。操作结果:若L为空表,则返回true,否则返回false
        bool Empty();

        // 初始条件:线性表已存在。操作结果:将L重置为空表
        bool Clear();

        // 初始条件:线性表已存在。操作结果:返回L中数据元素个数
        int Length();

        // 初始条件:线性表L已存在,1≤i≤ListLength(L)
        // 操作结果:用e返回第nIndex个数据元素的值,注意i是指位置,第1个位置的数组是从0开始
        bool GetAt(int nIndex, T& e);

        // 初始条件:线性表L已存在,1≤i≤ListLength(L)
        // 操作结果:返回第1个与e满足关系的数据元素的位序
        // 若这样的数据元素不存在,则返回值为0
        int Locate(const T& e);

        // 初始条件:线性表已存在,如果i<1,则插在头部;如果i>m_nLen,则插在尾部
        // 操作结果:第nIndex个位置之前插入新的数据元素e,长度加1 
        bool Insert(int nIndex, const T& e);

        // 初始条件:线性表L已存在
        // 操作结果:在顺序线性表的尾端添加一个元素,长度加1
        bool Pushback(const T& e);

        // 初始条件:线性表已存在,1≤i≤ListLength(L)
        // 操作结果:删除的第nIndex个数据元素,并用e返回其值,L的长度减1
        bool Delete(int nIndex, T& e);

        // 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法)
        bool CreateRandomList(size_t nCount);

        // 显示链表里面的元素
        void DisplayList();

        // 链表元素排序
        void SortList();

        // 反转线性表
        void ReverseList();

        explicit CLinkList()
            : m_pHead(nullptr)
            , m_nLen(0)
        {
        }

        ~CLinkList()
        {
        }

        template<class T>
        bool InitList()
        {
            m_pHead = new CLinkNode<T>;
            if (!m_pHead)
                return false;
            else
            {
                m_pHead->m_pNext = nullptr;
                return true;
            }
        }

        template<class T>
        bool Empty()
        {
            if (m_nLen)
                return false;
            else
                return true;
        }

        template<class T>
        bool Clear()
        {
            if (!m_pHead->m_pNext)
                return true;

            CLinkNode<T> *pNode = m_pHead->m_pNext;
            while (pNode)
            {
                m_pHead->m_pNext = pNode->m_pNext;
                pNode->m_pNext = nullptr;
                pNode = m_pHead->m_pNext;
            }

            m_nLen = 0;
            return true;
        }

        template<class T>
        int Length()
        {
            return m_nLen;
        }

        template<class T>
        bool GetAt(int nIndex, T& e)
        {
            if (!m_nLen)
                return false;
            if ((nIndex >= 1) && (nIndex <= m_nLen))
            {
                CLinkNode<T> *pNode = m_pHead->m_pNext;
                while (--nIndex)
                {
                    pNode = pNode->m_pNext;
                }

                e = pNode->m_data;

                return true;
            }
            return false;
        }

        template<class T>
        int Locate(const T& e)
        {
            int nIndex = 1;
            CLinkNode<T> *pNode = m_pHead->m_pNext;
            while (pNode)
            {
                if (e == pNode->m_data)
                {
                    return nIndex;
                }
                nIndex++;
                pNode = pNode->m_pNext;
            }
            return 0;
        }

        template<class T>
        bool Insert(int nIndex, const T& e)
        {
            // 还没初始化
            if (!m_pHead)
                return false;

            CLinkNode<T> *pNode = nullptr;
            if (nIndex <= 1)
            {
                pNode = new CLinkNode<T>;
                if (pNode)
                {
                    pNode->m_pNext = m_pHead->m_pNext;
                    pNode->m_data = e;
                    m_pHead->m_pNext = pNode;
                    m_nLen++;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                pNode = m_pHead;
                // --nIndex针对2<=nIndex<=m_nLen的情况
                // pNode针对nIndex>m_nLen的情况,也就是直接加到队尾
                while (--nIndex && pNode->m_pNext)
                {
                    pNode = pNode->m_pNext;
                }

                CLinkNode<T> *pNodeNew = new CLinkNode<T>;
                if (pNodeNew)
                {
                    pNodeNew->m_data = e;
                    pNodeNew->m_pNext = pNode->m_pNext;
                    pNode->m_pNext = pNodeNew;
                    m_nLen++;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        template<class T>
        bool Pushback(const T& e)
        {
            if (!m_pHead)
                return false;

            CLinkNode<T> *pNode = m_pHead;
            while (pNode->m_pNext)
            {
                pNode = pNode->m_pNext;
            }

            CLinkNode<T> *pNodeNew = new CLinkNode<T>;
            if (pNodeNew)
            {
                pNodeNew->m_data = e;
                pNodeNew->m_pNext = nullptr;
                pNode->m_pNext = pNodeNew;
                m_nLen++;
                return true;
            }
            else
            {
                return false;
            }
        }

        template<class T>
        bool Delete(int nIndex, T& e)
        {
            if (!m_pHead)
                return false;

            if ((nIndex >= 1) && (nIndex <= m_nLen))
            {
                CLinkNode<T> *pNode = m_pHead;
                // 找到待删除节点的前一个节点
                while (--nIndex)
                {
                    pNode = pNode->m_pNext;
                }

                CLinkNode<T> *pNext = pNode->m_pNext;
                e = pNext->m_data;
                pNode->m_pNext = pNext->m_pNext;
                delete pNext;
                m_nLen--;
                return true;
            }
            return false;
        }

        // 这个不能配合Delete和Clear使用,因为这里是批量申请内存空间的,不能单个删除
        template<class T>
        bool CreateRandomList(size_t nCount)
        {
            if (m_pHead || nCount < 1)
                return false;

            srand((unsigned int)time(0));
            m_pHead = new CLinkNode<T>;
            if (!m_pHead)
                return false;

            CLinkNode<T> *pNode = nullptr;
            try
            {
                pNode = new CLinkNode<T>[nCount];
            }
            catch (std::exception& e)
            {
                std::cout << "Standard exception: " << e.what() << std::endl;
            }

            m_pHead->m_pNext = pNode;           // 连上头节点
            for (size_t i = 0; i < nCount; i++)
            {
                pNode->m_pNext = pNode + 1;
                pNode->m_data = rand() % 100 + i;
                pNode++;
            }
            (pNode - 1)->m_pNext = nullptr;     // 最后一个节点
            
            m_nLen = nCount;

            return true;
        }

        template<class T>
        void DisplayList()
        {
            if (!m_pHead->m_pNext)
                return;
            int nIndex = 1;
            CLinkNode<T> *pNode = m_pHead->m_pNext;
            while (pNode)
            {
                std::cout << nIndex++ << ": " << pNode->m_data << "\t";
                pNode = pNode->m_pNext;
            }
            std::cout << std::endl;
        }

        template<class T>
        void SortList()
        {
            if (m_nLen < 2)
                return;
            
            CLinkNode<T> *pNewHead = new CLinkNode<T>;              // 新建一个临时表头
            if (!pNewHead)
                return;

            CLinkNode<T> *pNode = m_pHead->m_pNext;
            CLinkNode<T> *pNewNode = nullptr;
            pNewHead->m_pNext = nullptr;
            
            while (m_pHead->m_pNext)                                // 从原链表的前面一个个摘除
            {
                // 从原链表中摘出一个元素
                pNode = m_pHead->m_pNext;
                m_pHead->m_pNext = m_pHead->m_pNext->m_pNext;
                pNode->m_pNext = nullptr;

                pNewNode = pNewHead;                                // pNewNode指向pNewHead的头节点

                do 
                {
                    if (!pNewNode->m_pNext)                         // 找到最后节点处了
                    {
                        pNewNode->m_pNext = pNode;
                        break;
                    }

                    if (pNode->m_data > pNewNode->m_pNext->m_data)
                    {
                        pNewNode = pNewNode->m_pNext;
                        continue;
                    }
                    else
                    {
                        pNode->m_pNext = pNewNode->m_pNext;
                        pNewNode->m_pNext = pNode;
                        break;
                    }
                } while (pNewNode);
            }

            m_pHead->m_pNext = pNewHead->m_pNext;
            delete pNewHead;
        }

        template<class T>
        void ReverseList()
        {
            if (m_nLen < 2)
                return;

            CLinkNode<T> *pFirst = m_pHead->m_pNext;             // 第一个节点
            CLinkNode<T> *pSecond = m_pHead->m_pNext->m_pNext;    // 第二个节点
            CLinkNode<T> *pTemp = nullptr;
            pFirst->m_pNext = nullptr;

            while (pSecond)
            {
                pTemp = pSecond->m_pNext;
                pSecond->m_pNext = pFirst;
                pFirst = pSecond;
                pSecond = pTemp;
            }
            m_pHead->m_pNext = pFirst;
        }

    private:
        CLinkNode<T>    *m_pHead;
        int             m_nLen;
    };
}


代码参考了 http://blog.youkuaiyun.com/freesum/article/details/7355192,不过算法什么的都是自己写的。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值