zoukankan      html  css  js  c++  java
  • C++双向循环链表实现

    双向循环链表C++实现

    1.单链表:

    结构图:

    2.双向链表:

    3.双向循环链表:

    对于本程序中,则是给定一个_head  头结点,而不是指针,因为这样更加方便避免一些空判断问题

    /*
    版权信息:狼
    文件名称:BidCirList.h
    文件标识:
    文件摘要:
        利用C++实现简单的双向链表功能。增,删,查,改
        //太烦了。。我直接给个 带头结点的  表
        //swap 移花接木已经是个给力的方法。。just try
    当前版本:1.1
    作    者:狼
    完成时间:2015-12-13
    
    */
    #ifndef _BIDCIRLIST_H
    #define _BIDCIRLIST_H
    
    #include"afxstd.h"
    
    typedef int DataType;
    typedef struct ListNode
    {
        ListNode(DataType x=0)
        : _data(x)
        //默认初始化是自环而非  NULL
        , _prev(this)
        , _late(this)
        {}
    
        DataType _data;
        struct ListNode* _prev;
        struct ListNode* _late;
    }ListNode;
    
    class BidCirList
    {
    public:
        BidCirList()
            :_head(0)
        {}
    
        BidCirList(DataType *array, size_t n = 0)
            :_head(0)
        {
            size_t i = 0;
            while (n--)
            {
                InsertAter(array[i++]);
            }
        }
    
        BidCirList(BidCirList & list)
            :_head()
        {
            ListNode* cur = list._head._prev;
            while (cur)
            {
                InsertAter(cur->_data);
                cur = cur->_prev;
                if (cur == &list._head)
                    break;
            }
        }
    
        ~BidCirList()
        {
            Destoty();
        }
        
        BidCirList operator+(BidCirList& list)
        {
            BidCirList tmp(*this);
            ListNode* cur = list._head._prev;
    
            while (cur != &list._head)
            {
                tmp.InsertAter(cur->_data);
                cur = cur->_prev;
            }
            return tmp;
        }
    
        BidCirList& operator = (BidCirList& list)
        {
            if (this != &list)
            {
                BidCirList S(list);
    
                Swap(S);
            }
            return *this;
        }
    
        //清空空间
        void Destoty()
        {
            ListNode*cur = &_head;
            while (cur->_prev != &_head)
            {
                DelPrev();
            }
        }
    
        //删除结点之前的结点。默认为头
        void DelPrev(ListNode *del = NULL)
        {
            if (_head._prev == &_head)
                return;
            if (del == NULL)
            {
                //删除头之前
                _head._prev = _head._prev->_prev;
                delete _head._prev->_late;
    
                _head._prev->_late = &_head;
            }
            else
            {
                del->_prev = del->_prev->_prev;
                delete del->_prev->_late;
    
                del->_prev->_late = del;
            }
        }
    
        //删除结点之后一个,,默认为头
        void DelLate(ListNode *del = NULL)
        {
            if (_head._prev == &_head)
                return;
            if (del == NULL)
            {
                _head._late = _head._late->_late;
                delete _head._late->_prev;
    
                _head._late->_prev = &_head;
            }
            else
            {
                del->_late = del->_late->_late;
                delete del->_late->_prev;
    
                del->_late->_prev = del;
            }
        }
    
        //在结点之前插入,默认为头
        void InsertAter(DataType x ,ListNode* ins= NULL)
        {
            ListNode* tmp = new ListNode(x);
    
            if (ins == NULL)
            {
                tmp->_prev = &_head;
                tmp->_late = _head._late;
    
                tmp->_late->_prev = tmp;
                tmp->_prev->_late = tmp;
            }
            else
            {
                tmp->_prev = ins;
                tmp->_late = ins->_late;
    
                tmp->_late->_prev = tmp;
                tmp->_prev->_late = tmp;
            }
        }
    
        ListNode* Find(DataType x)
        {
            ListNode* cur = _head._prev;
            while (cur)
            {
                if (cur == &_head)
                    return NULL;
                if (cur->_data == x)
                {
                    return cur;
                }
                cur = cur->_prev;
            }
        }
    
        void Erase(ListNode * node)
        {
            if (node == &_head)
            {
                return;
            }
            else
            {
                ListNode* tmp = node;
                node->_prev->_late = node->_late;
                node->_late->_prev = node->_prev;
                delete tmp;
                tmp = NULL;
            }
        }
    
        //反向打印
        void PrintPrev()
        {
            ListNode* cur = _head._prev;
            while (cur)
            {
                if (cur == &_head)
                    break;
                cout << cur->_data << " -> ";
                cur = cur->_prev;
            }
            cout << " Over! " << endl;
        }
        //正向打印
        void PrintLate()
        {
            ListNode* cur = _head._late;
    
            while (cur)
            {
                if (cur == &_head)
                    break;
                cout << cur->_data << " -> ";
                cur = cur->_late;
            }
            cout << " Over! " << endl;
        }
    
        void Swap(BidCirList &list)
        {
            ::swap(_head._prev->_late, list._head._prev->_late);
            ::swap(_head._prev, list._head._prev);
    
            ::swap(_head._late->_prev, list._head._late->_prev);
            ::swap(_head._late, list._head._late);
    
        }
        
    private:
        ListNode _head;
    };
    
    #endif
  • 相关阅读:
    Android Gradle Plugin指南(五)——Build Variants(构建变种版本号)
    文件内容操作篇clearerr fclose fdopen feof fflush fgetc fgets fileno fopen fputc fputs fread freopen fseek ftell fwrite getc getchar gets
    文件操作篇 close creat dup dup2 fcntl flock fsync lseek mkstemp open read sync write
    嵌入式linux应用程序调试方法
    version control system:git/hg/subversion/cvs/clearcase/vss。software configruation management。代码集成CI:Cruisecontrol/hudson/buildbot
    最值得你所关注的10个C语言开源项目
    如何记录linux终端下的操作日志
    CentOS 5.5 虚拟机安装 VirtualBox 客户端增强功能
    sizeof, strlen区别
    C/C++嵌入式开发面试题
  • 原文地址:https://www.cnblogs.com/lang5230/p/5046960.html
Copyright © 2011-2022 走看看