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
时间: 2024-11-04 13:10:18

C++双向循环链表实现的相关文章

第33课 双向循环链表的实现

1. DTLib中双向链表的设计思路 (1)数据结点之间在逻辑上构成双向循环,这有别于Linux内核链表的实现. (2)头结点仅用于结点的定位,而Linux内核链表是将头结点作为循环的一部分. 2. 实现思路 (1)通过模板定义DualCircleList类,继承自DualLinkList类 (2)在DualCircleList内部使用Linux内核链表进行实现(另类实现) (3)使用struct list_head定义DualCircleList的头结点 (4)特殊处理:循环遍历时忽略头结点

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

双向循环链表

//双向循环链表 typedef int datatype; //方便修改 //当然也可以写成模板来适应更多的数据类型 struct dclink{ datatype data;//数据定义 struct dclink *pre; struct dclink *next;//前驱和后继指针 }; class DCLink { public: DCLink();//default constructor DCLink(datatype data);//单参constructor void add(

算法导论13:双向循环链表 2016.1.13

今天这个又打了很长时间,本来觉得数据结构就是那样,不过是一种思维,但是实际上真正自己打和想象中差距还是很大,需要考虑到各种细节. 今天这个问题有一个比较有意思的应用,就是“约瑟夫环问题”. 具体可以参见百度百科: http://baike.baidu.com/link?url=poA1Aanlptc6yzP1puYhSw_0RQjRAplhPfHwk6eoiqMNxw6WigCEbexxZ8a9SUbrMGokpPbKNzVYw308xjeEw_ 读完问题就可以发现,这个问题用链表就是一个很完美

C++__双向循环链表(练习)

双向循环链表 link.h #ifndef LINK_H_ #define LINK_H_ #define HEADER 0 #define TAIL -1 typedef int data_type; enum LINK_OP { LINK_ERR = -1, LINK_OK }; class LINK { private: LINK *last; data_type data; LINK *next; public: LINK(); LINK(data_type data); virtual

c语言编程之双向循环链表

双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define element int 4 typedef struct Node{ 5 element data; 6 struct Node *next; 7 struct Node *prior; 8 }*pNode; 9 10 //build a new double loop list 11

线性表.04.链式存储结构(双向循环链表)

以下是用双向循环链表实现的线性表 #include <stdio.h> #include <stdlib.h> #include <time.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int ElemType;//ElemType这里假设为int,可以根据需要进行更改 typedef int Status;//Status是函数的类型,其值是函数结果状态代码,如OK等 t

小猪的数据结构辅助教程——2.7 线性表中的双向循环链表

小猪的数据结构辅助教程--2.7 线性表中的双向循环链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.了解引入双向循环链表的原因 2.熟悉双向循环链表的特点以及存储结构 3.掌握双向循环链表的一些基本操作的实现逻辑 4.掌握逆序输出双向循环链表元素逻辑 1.双向循环链表的引入 2.双向循环链表的存储结构 双向循环链表的特点: 上面也说了,空间换时间,比起循环链表只是多了一个指向前驱的指针 特点的话: 判断空表:L ->next = L -> prior = L; 存

C++双向循环链表

DuLink: #include<iostream> using namespace std; typedef int elemType; typedef struct DulNode { elemType data; DulNode *prior; DulNode *next; }*DuList; void InitList(DuList *L) { *L = new DulNode; (*L)->next = (*L)->prior = *L; } int LengthList