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 ~LINK();

    data_type getData() const;
    LINK *getLast() const;
    LINK *getNext() const;
    void setData(data_type data);
    void setLast(LINK *last);
    void setNext(LINK *next);

//    LINK *CreateList(data_type data);
//    void DestroyList(LINK *pList);
    int InsertItem(LINK *pList, data_type tData, int iOffset);
    int DeleteItem(LINK *pList, data_type *pData, int iOffset);
    int UpdateItem(LINK *pList, data_type tNew, data_type tOld);
    int SearchItem(LINK *pList, data_type tData);
    void ShowList(LINK *pList, int iFlag);
    void operator delete(void *pList);
};

#endif /* LINK_H_ */

link.cpp

#include "LINK.h"
#include <iostream>
using namespace std;

LINK::LINK() {
    // TODO Auto-generated constructor stub
    this->setData(0);
    this->setLast(this);
    this->setNext(this);
}

LINK::LINK(data_type data) {
    // TODO Auto-generated constructor stub
    this->setData(data);
    this->setLast(this);
    this->setNext(this);
}

LINK::~LINK() {
    // TODO Auto-generated destructor stub
}

data_type LINK::getData() const {
    return data;
}

LINK *LINK::getLast() const {
    return last;
}

LINK *LINK::getNext() const {
    return next;
}

void LINK::setData(data_type data) {
    this->data = data;
}

void LINK::setLast(LINK *last) {
    this->last = last;
}

void LINK::setNext(LINK *next) {
    this->next = next;
}

/*
 LINK *LINK::CreateList(data_type data) {
 LINK *pList = new LINK(data);
 if (!pList)
 return NULL;
 pList->setLast(pList);
 pList->setNext(pList);

 return pList;
 }

 void LINK::DestroyList(LINK *pList) {
 if (!pList)
 return;

 LINK *Tmp = pList->getNext();
 while (pList != Tmp) {
 pList->setNext(Tmp->getNext());
 delete Tmp;
 Tmp = pList->getNext();
 }
 delete pList;

 return;
 }
 */

int LINK::InsertItem(LINK *pList, data_type tData, int iOffset) {
    if ((!pList) || -1 > iOffset)
        return LINK_ERR;

    LINK *New = new LINK(tData);
    if (!New)
        return LINK_ERR;
    LINK *Tmp = NULL;
    switch (iOffset) {
    case HEADER:
        Tmp = pList->getNext();
        New->setNext(Tmp);
        Tmp->setLast(New);
        New->setLast(pList);
        pList->setNext(New);
        break;

    case TAIL:
        Tmp = pList->getLast();
        New->setLast(Tmp);
        Tmp->setNext(New);
        New->setNext(pList);
        pList->setLast(New);
        break;

    default:
        Tmp = pList->getNext();
        while (iOffset--) {
            Tmp = Tmp->getNext();
        }
        New->setNext(Tmp);
        New->setLast(Tmp->getLast());
        Tmp->getLast()->setNext(New);
        Tmp->setLast(New);
        break;
    }

    return LINK_OK;
}

int LINK::DeleteItem(LINK *pList, data_type *pData, int iOffset) {
    if ((!pList) || (!pData) || -1 > iOffset)
        return LINK_ERR;

    LINK *Del = NULL;
    switch (iOffset) {
    case HEADER:
        Del = pList->getNext();
        *pData = Del->getData();
        Del->getNext()->setLast(pList);
        pList->setNext(Del->getNext());
        break;

    case TAIL:
        Del = pList->getLast();
        *pData = Del->getData();
        Del->getLast()->setNext(pList);
        pList->setLast(Del->getLast());
        break;

    default:
        Del = pList->getNext();
        while (iOffset--) {
            Del = Del->getNext();
        }
        if (pList == Del) {
            cout << "iOffset error" << endl;
            return LINK_ERR;
        }
        *pData = Del->getData();
        Del->getLast()->setNext(Del->getNext());
        Del->getNext()->setLast(Del->getLast());
        break;
    }
    Del->setNext(NULL);
    delete Del;

    return LINK_OK;
}

int LINK::UpdateItem(LINK *pList, data_type tNew, data_type tOld) {
    if (!pList)
        return LINK_ERR;

    int flage = 1;
    LINK *Tmp = pList;
    while (flage) {
        if (Tmp->getData() == tOld) {
            Tmp->setData(tNew);
            break;
        }
        Tmp = Tmp->getNext();
        if (Tmp == pList)
            flage = 0;
    }

    return LINK_OK;
}

int LINK::SearchItem(LINK *pList, data_type tData) {
    if (!pList)
        return LINK_ERR;

    int flage = 1;
    int i = 0;
    LINK *Tmp = pList;
    while (flage) {
        if (Tmp->getData() == tData) {
            cout << "The data is No." << i << endl;
        }
        Tmp = Tmp->getNext();
        i++;
        if (Tmp == pList)
            flage = 0;
    }

    return LINK_OK;
}

void LINK::ShowList(LINK *pList, int iFlag) {
    if (!pList)
        return;

    int flage = 1;
    LINK *Tmp = NULL;
    switch (iFlag) {
    case HEADER:
        Tmp = pList;
        while (flage) {
            cout << Tmp->getData() << "  ";
            Tmp = Tmp->getNext();
            if (Tmp == pList)
                flage = 0;
        }
        break;

    case TAIL:
        Tmp = pList;
        while (flage) {
            cout << Tmp->getData() << "  ";
            Tmp = Tmp->getLast();
            if (Tmp == pList)
                flage = 0;
        }
        break;
    default:
        break;
    }
    cout << endl;

    return;
}

void LINK::operator delete(void *pList) {
    if (!pList)
        return;

    LINK *Tmp = ((LINK *) pList)->getNext();
    while ((Tmp != pList) && (NULL != Tmp)) {
        cout<<Tmp->getData()<<"  ";
        ((LINK *)pList)->setNext(Tmp->getNext());
        free(Tmp);
        Tmp = ((LINK *) pList)->getNext();
    }
    cout<<((LINK *) pList)->getData()<<endl;
    free(pList);

    return;
}

main.cpp

#include "LINK/LINK.h"
#include <iostream>
using namespace std;

void function() {
    int i = 9;
    LINK *pList = new LINK(i);
    if (!pList)
        return;
    while (i--) {
        pList->InsertItem(pList, i, 0);
    }
    pList->ShowList(pList, 0);
    pList->ShowList(pList, -1);
    pList->InsertItem(pList, 999, 0);
    pList->ShowList(pList, -1);
    pList->InsertItem(pList, 666, -1);
    pList->ShowList(pList, -1);
    pList->InsertItem(pList, 333, 33);
    pList->ShowList(pList, 0);
    pList->DeleteItem(pList, &i, 0);
    pList->ShowList(pList, 0);
    pList->DeleteItem(pList, &i, -1);
    pList->ShowList(pList, 0);
    pList->DeleteItem(pList, &i, 32);
    pList->ShowList(pList, 0);
    pList->UpdateItem(pList, 333, 0);
    pList->ShowList(pList, 0);
    pList->SearchItem(pList, 333);
    delete pList;
    cout << "end" << endl;
}

int main() {
    function();
    return 0;
}
时间: 2024-11-23 17:17:14

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语言编程之双向循环链表

双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. 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++双向循环链表实现

双向循环链表C++实现 1.单链表: 结构图: 2.双向链表: 3.双向循环链表: 对于本程序中,则是给定一个_head  头结点,而不是指针,因为这样更加方便避免一些空判断问题 /* 版权信息:狼 文件名称:BidCirList.h 文件标识: 文件摘要: 利用C++实现简单的双向链表功能.增,删,查,改 //太烦了..我直接给个 带头结点的 表 //swap 移花接木已经是个给力的方法..just try 当前版本:1.1 作 者:狼 完成时间:2015-12-13 */ #ifndef _

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