zoukankan      html  css  js  c++  java
  • C++ 模板双向不循环链表!!

    CTDChain<T,sort,equal,pointer> * nodeTemp = NULL;

    ------------------------------------------------------------------------------

    using namespace std;
    //双向不循环链表
    //sort 指示是否有序
    //equal 指示当出现相同节点时的处理方法
    //pointer 指示是否是一个指针类型,在析构时必不可少
    template <class T,
            const int sort = 0,
            const CtEqualMethod equal = CtEM_ALLOW,
            const int pointer = 1> 
    --------------------------------------------------------------------------------------
    class CTDChain
    {
    public:
        CTDChain    * m_pPrev;
        CTDChain    * m_pNext;
        T            m_tItem;
     
    protected:
     
        // 向链表头搜索一个节点, 失败时返回空指针,direct指示搜索方向
        virtual CTDChain * SearchPrev(T &item)
        {
            if( TypeComp(m_tItem,item, CtCS_EQ) ) return this;
            else if( m_pPrev )
                return m_pPrev->CTDChain<T,sort,equal,pointer>:: SearchPrev(item);
            else return NULL;
        }
     
     
        // 向链表尾部搜索一个节点, 失败时返回空指针,direct指示搜索方向
        virtual CTDChain * SearchNext(T &item)
        {
            if( TypeComp(m_tItem,item, CtCS_EQ) ) return this;
            else if( m_pNext )
                return m_pNext->CTDChain<T,sort,equal,pointer>:: SearchNext(item);
            else return NULL;
        }
     
     
        //从本节点开始向后查找最小的节点,由排序函调用
        virtual CTDChain * SmallestNext()
        {
            CTDChain<T,sort,equal,pointer> * nodeNext = m_pNext;
            CTDChain<T,sort,equal,pointer> * nodeSmall = this;
     
            while( nodeNext )
            {
                if( nodeSmall->m_tItem > nodeNext->m_tItem ) nodeSmall = nodeNext;
                nodeNext = nodeNext->m_pNext;
            }
            return nodeSmall;
        }
     
    public:
     
        CTDChain(): m_pPrev(0), m_pNext(0), m_tItem(0){};
     
     
        CTDChain(T &item): m_pPrev(0), m_pNext(0), m_tItem(0)
        {
            CTDChain<T,sort,equal,pointer>:: SetNodeItem(item);
        }
     
     
        //考贝构造函数
        CTDChain(CTDChain & node)
        {
            m_pPrev = node.m_pPrev;
            m_pNext = node.m_nNext;
            if( pointer )
            {
                if( !m_tItem ) m_tItem = new T;
                *m_tItem = *(node.nodeItem);
            }
            else m_tItem = node.nodeItem;
     
        }
     
     
        //析构时自动删除在它后面的节点
        ~CTDChain()
        {
            if( pointer && m_tItem ) delete m_tItem;
            if( m_pPrev ) m_pPrev->m_pNext = NULL;
            if( m_pNext )
            {
                m_pNext->m_pPrev = NULL;
                delete m_pNext;
                m_pNext = NULL;
            }
        }
     
     
        // 找到链表头节点
        CTDChain * Head()
        {
            if( !m_pPrev ) return this;
            else return m_pPrev->CTDChain<T,sort,equal,pointer>:: Head();
        }
     
     
        // 找到链表尾节点
        CTDChain * Tail()
        {
            if( !m_pNext ) return this;
            else return m_pNext->CTDChain<T,sort,equal,pointer>:: Tail();
        }
     
     
        //统计链表中节点个数
        int NodeNum()
        {
            int nNum = 0;
            CTDChain<T,sort,equal,pointer> * nodeTemp = Head();
            while( nodeTemp )
            {
                nNum++;
                nodeTemp = nodeTemp->m_pNext;
            }
            return nNum;
        }
     
     
        //从链表中移走一个节点
        //注意:Pop头节点时,要有指针记录新的头节点
        virtual void Pop()
        {
            if( m_pPrev ) m_pPrev->m_pNext = m_pNext;
            if( m_pNext ) m_pNext->m_pPrev = m_pPrev;
            m_pPrev = m_pNext = NULL;
        }
     
     
        //设置一个节点的值,替换掉原有的值
        virtual int SetNodeItem(const T &item)
        {
            if( pointer && m_tItem ) delete m_tItem;
            m_tItem = item;
            return CtRC_REPLACE;
        }
     
        int TypeComp(const T &a, const T&b, CtCompartStyle style = CtCS_GT)
        {
            if( pointer )
            {
                switch( style )
                {
                case CtCS_GT: return ((*a) >  (*b)); break;
                case CtCS_GE: return ((*a) >= (*b)); break;
                case CtCS_EQ: return ((*a) == (*b)); break;
                case CtCS_NE: return ((*a) != (*b)); break;
                case CtCS_LT: return ((*a) <  (*b)); break;
                case CtCS_LE: return ((*a) <= (*b)); break;
                default: return 0;
                }
            }
            else
            {
                switch( style )
                {
                case CtCS_GT: return (a >  b); break;
                case CtCS_GE: return (a >= b); break;
                case CtCS_EQ: return (a == b); break;
                case CtCS_NE: return (a != b); break;
                case CtCS_LT: return (a <  b); break;
                case CtCS_LE: return (a <= b); break;
                default: return 0;
                }
            }
                return 1;
        }
     
     
        // 搜索一个节点, 失败时返回空指针
        virtual CTDChain * Search(T &item)
        {
            CTDChain<T,sort,equal,pointer> * nodeTemp = NULL;
     
            if( TypeComp(m_tItem,item,CtCS_EQ) ) return this;
            if( sort )
            {//有序
                if( TypeComp(item,m_tItem) ) nodeTemp = CTDChain<T,sort,equal,pointer>:: SearchNext(item);
                else nodeTemp = CTDChain<T,sort,equal,pointer>:: SearchPrev(item);
            }
            else
            {//无序
                nodeTemp = CTDChain<T,sort,equal,pointer>:: SearchPrev(item);
                if( !nodeTemp ) nodeTemp = CTDChain<T,sort,equal,pointer>:: SearchNext(item);
            }
            return nodeTemp;
        }
     
     
        //插入一个节点在本节点之前,node必须是一个单节点
        virtual int PushPrev(CTDChain * node)
        {
            node->m_pNext = this;
            node->m_pPrev = m_pPrev;
            if( m_pPrev ) m_pPrev->m_pNext = node;
            m_pPrev = node;
            return CtRC_SUCCESS;
        }
     
     
        //插入一个节点在本节点之后,node必须是一个单节点
        virtual int PushNext(CTDChain * node)
        {
            node->m_pNext = m_pNext;
            node->m_pPrev = this;
            if( m_pNext ) m_pNext->m_pPrev = node;
            m_pNext = node;
            return CtRC_SUCCESS;
        }
     
     
        //插入一个单节点
        virtual int Push(CTDChain * &node)
        {
            CTDChain<T,sort,equal,pointer> * nodeTemp;
     
            if( !node ) return CtRC_FAIL;
     
            //判断相同节点
            switch( equal )
            {
            case CtEM_REJECT:    //不允许出现相同节点
            case CtEM_REPLACE:    //替换相同节点
                nodeTemp = CTDChain<T,sort,equal,pointer>:: Search(node->m_tItem);
                if( NULL == nodeTemp ) break;
                if( equal == CtEM_REJECT ) return CtRC_REJECT;
                return nodeTemp->CTDChain<T,sort,equal,pointer>:: SetNodeItem(node->m_tItem);
                break;
            case CtEM_ALLOW:    //允许出现相同节点
            default:
                break;
            }
     
            //查找插入点,这里不用考虑相等情况
            nodeTemp = this;
            if( sort )
            {//有序
                if( TypeComp(node->m_tItem,nodeTemp->m_tItem) )
                {//向表尾查找
                    while( TypeComp(node->m_tItem,nodeTemp->m_tItem) )
                    {
                        if( !nodeTemp->m_pNext ) break;
                        nodeTemp = nodeTemp->m_pNext;
                    }
                }
                else
                {//向表头查找
                    while( TypeComp(nodeTemp->m_tItem,node->m_tItem) )
                    {
                        if( !nodeTemp->m_pPrev )
                            return nodeTemp->CTDChain<T,sort,equal,pointer>:: PushPrev(node);
                        nodeTemp = nodeTemp->m_pPrev;
                    }
                }
            }
            else
            {//无序
                nodeTemp = CTDChain<T,sort,equal,pointer>:: Tail();
            }
     
            //在上面还有一个插入点,是插入在链表的头部
            return nodeTemp->CTDChain<T,sort,equal,pointer>:: PushNext(node);
        }
     
        virtual int Push(T &item)
        {
            CTDChain<T,sort,equal,pointer> * nodeTemp;
            int nRet;
     
            if( NULL == (nodeTemp = new CTDChain<T,sort,equal,pointer>(item)) )
            {
                RAISE_ERROR("警告:申请内存失败");
                return CtRC_FAIL;
            }
     
            nRet = CTDChain<T,sort,equal,pointer>:: Push(nodeTemp);
            switch( nRet )
            {
            case CtRC_FAIL: break;
            case CtRC_SUCCESS: break;
            case CtRC_REPLACE:
                if( pointer ) nodeTemp->m_tItem = NULL;
            case CtRC_REJECT:
                delete nodeTemp;
                break;
            default: break;
            }
     
            return nRet;
        }
     
     
        //插入另外一个链表的所有节点,返回值是插入节点的个数
        //插入完成后,原链表被删除
        virtual int Merge(CTDChain * &chain)
        {
            CTDChain<T,sort,equal,pointer> * nodeTemp;
            int nRet, nNum = 0;
            if( !chain ) return 0;
     
            //先截断原链表
            if( chain->m_pPrev )
            {
                chain->m_pPrev->m_pNext = NULL;
                chain->m_pPrev = NULL;
            }
     
            //如果允许相同节点且无序
            if( equal == CtEM_ALLOW && !sort )
            {
                nNum = chain->NodeNum();
                nodeTemp = CTDChain<T,sort,equal,pointer>:: Tail();
                nodeTemp->m_pNext = chain;
                chain->m_pPrev = nodeTemp;
            }
            else
            {
                nodeTemp = chain;
                while( nodeTemp )
                {
                    chain = chain->m_pNext;
                    nodeTemp->Pop();
                    nRet = CTDChain<T,sort,equal,pointer>:: Push(nodeTemp);
                    switch( nRet )
                    {
                    case CtRC_SUCCESS: nNum++; break;
                    case CtRC_REPLACE:
                        if( pointer ) nodeTemp->m_tItem = NULL;
                    case CtRC_REJECT:
                    case CtRC_FAIL:
                        delete nodeTemp;
                        break;
                    default: break;
                    }
                    nodeTemp = chain;
                }
            }
            chain = NULL;
            return nNum;
        }
     
     
        //排序函数, 它使用T的操作符 '>'
        virtual void Sort()
        {
            CTDChain<T,sort,equal,pointer> * nodeSmall;
            CTDChain<T,sort,equal,pointer> * nodeTemp = CTDChain<T,sort,equal,pointer>:: Head();
     
            while( nodeTemp )
            {
                nodeSmall = nodeTemp->CTDChain<T,sort,equal,pointer>:: SmallestNext();
                if( nodeSmall != nodeTemp )
                {//最小节点不是当前节点
                    nodeSmall->CTDChain<T,sort,equal,pointer>:: Pop();
                    nodeTemp->CTDChain<T,sort,equal,pointer>:: PushPrev(nodeSmall);
                }
                else nodeTemp = nodeTemp->m_pNext;
            }
        }
  • 相关阅读:
    .Net 控制台动态刷新使用
    VS 将!=转换成 ≠
    C# 自定义Html分页
    .NET MVC ModelBinder基本使用
    C# 重启电脑 程序自启动
    ASP.NET JsonResult返回日期格式及首字母大写解决
    java快速排序代码实现
    系统高可靠的设计需要考虑哪些方面
    sentinel源码学习--transport模块
    TiDB学习笔记分享--存储篇
  • 原文地址:https://www.cnblogs.com/the-tops/p/5661323.html
Copyright © 2011-2022 走看看