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:
    data_type data;
    LINK *next;
    LINK *last;
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 tData);
//    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 tData) {
    LINK *pList = new LINK(tData);
    if (!pList)
        return NULL;

    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;
    pList = NULL;

    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();
        Tmp->setNext(New);
        New->setNext(pList);
        New->setLast(Tmp);
        pList->setLast(New);
        break;

    default:
        Tmp = pList->getNext();
        while (iOffset--) {
            Tmp = Tmp->getNext();
        }
        New->setNext(Tmp->getNext());
        Tmp->getNext()->setLast(New);
        New->setLast(Tmp);
        Tmp->setNext(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();
        pList->setNext(Del->getNext());
        Del->getNext()->setLast(pList);
        break;

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

    default:
        Del = pList->getNext();
        while (iOffset--) {
            Del = Del->getNext();
        }
        Del->getNext()->setLast(Del->getLast());
        Del->getLast()->setNext(Del->getNext());
        *pData = Del->getData();
        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 i = 0;
    int flage = 1;
    LINK *Tmp = pList;
    while (flage) {
        if (Tmp->getData() == tData) {
            cout << "The data is No." << i << endl;
            return i;
        }
        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)) {
        ((LINK *)pList)->setNext(Tmp->getNext());
        cout<<Tmp->getData()<<"  ";
        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);
    }

//    link.ShowList(pList, 0);
    pList->ShowList(pList, -1);
    pList->InsertItem(pList, 999, 7);
    pList->ShowList(pList, -1);
    pList->DeleteItem(pList, &i, 1);
    pList->ShowList(pList, -1);
    pList->DeleteItem(pList, &i, 11);
    pList->ShowList(pList, -1);
    pList->UpdateItem(pList, 888, 999);
    pList->ShowList(pList, -1);
    pList->SearchItem(pList, 5);
    pList->ShowList(pList, -1);
//    pList->DestroyList(pList);
    delete pList;
    cout << "end" << endl;

}

int main() {
    function();
    return 0;
}
时间: 2024-10-12 19:00:31

C++__双向链表(练习)的相关文章

linux内核-双向链表

linux中的经典宏定义 offsetof 定义:offsetof在linux内核的include/linux/stddef.h中定义. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(MEMBER)在此结构体中的偏移量. (01) ( (TYPE *)0 ) 将零转型为TYPE类型指针,即TYPE类型的指针的地址是0. (02) ((TYPE *)0)->MEMBER

Linux内核中双向链表的经典实现

Linux内核中双向链表的经典实现 概要 前面一章"介绍双向链表并给出了C/C++/Java三种实现",本章继续对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法.其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of.内容包括:1. Linux中的两个经典宏定义2. Linux中双向链表的经典实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3562146.html 更多

Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(

数据结构第四篇——线性表的链式存储之双向链表

?注:未经博主同意,不得转载. 前面讨论的单链表,每个结点中只有一个指针域,用来存放指向后继结点的指针,因此,从某个结点出发只能顺时针往后查找其他结点.若要查找某个结点的直接前驱,则需要从头指针开始沿链表探寻,处理起来十分不方便.为克服单链表的这一缺点,可引入双向链表. 双向链表中每一个结点含有两个指针域,一个指针指向其直接前驱结点,另一个指针指向直接后继结点.和单链表类似,双向链表一般也只有头指针唯一确定:同样也可设头结点,使得双向链表的某些操作简便一些. 双向链表结构定义如下:  双向链表是

双向链表(一)

参考: http://blog.sina.com.cn/s/blog_7d44748b01013fsf.html    (写的太好啦) http://blog.163.com/haibianfeng_yr/blog/static/34572620201453061036702/ 双(向)链表中有两条方向不同的链,即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前趋的指针域prior.双向链表在查找时更方便 特别是大量数据的遍历 注意:    ①双链表由头指针head惟一确定的. 

显示数据库中的存储过程__转

It's no easy trick to see stored procedures in a database programmatically with a scripting language like ASP. If you're using MS Access, you're out of luck. Access provides no way to see the actual meat of a stored procedure although you can get the

c语言双向链表

typedef int ElemType; typedef struct _Node { ElemType value; struct _Node* pnext; struct _Node* prev; }node, *pNode; //创建双向链表 pNode Create_Double_List(int count) { pNode pn = NULL; pNode pb = NULL; pNode phead = (pNode)malloc(sizeof(node)); printf("请

Android 5.0 怎样正确启用isLoggable(二)__原理分析

前置文章 <Android 5.0 怎样正确启用isLoggable(一)__使用具体解释> 概要 在上文<Android 5.0 怎样正确启用isLoggable(一)__使用具体解释>中分析了isLoggable的用法,本文主要分析isLoggable实现原理以及user版系统root后永久enable isLoggable的原理,并使用脚本自己主动设置isLoggable相关属性. 本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处

剑指offer:二叉搜索树与双向链表

1.题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2.解题思路: (1)将左子树构造成双向链表,并返回链表头节点: (2)定位左子树双链表的尾节点: (3)如果左子树链表不为空,将当前root连缀其链尾: (4)将右子树构造出双向链表,并返回链表头节点: (5)如果右子树链表不为空,将当前root连缀其表头: (6)根据左子树链表是否为空,确定返回的节点. 3.JavaScript实现: function Conv