C++ 双向链表

#include<iostream>
using namespace std;

template<class T>
struct DNode
{
public:    
    T value; // 数据域
    DNode *prev; // 前驱
    DNode *next; // 后继
public:
    DNode() { } // 默认构造
    DNode(T t, DNode *prev, DNode *next)
    {
        this->value = t;
        this->prev = prev;
        this->next = next;
    }
};

// 双向链表基础操作
template<class T>
class DoubleLink
{
public:
    DoubleLink(); // 默认构造
    ~DoubleLink(); // 析构
    
    int size(); // 大小
    int is_empty(); // 判断是否为空
    
    T get(int index); // 获取结点
    T get_first(); // 获取首结点
    T get_last(); // 获取尾结点
    
    int insert(int index, T t); // 在 index 位置插入数据为 t 的结点
    int insert_first(T t); // 头插
    int append_last(T t); // 尾加
    
    int del(int index); // 删除第 index 位置的结点
    int delete_first(); // 删除头结点
    int delete_last(); // 删除尾结点

private:
    int count;
    DNode<T> *phead;
private:
    DNode<T> *get_node(int index);
};

// DoubleLink 构造函数
template<class T>
DoubleLink<T>::DoubleLink() : count(0)
{
    // 创建“表头”。注意:表头没有存储数据
    phead = new DNode<T>();
    phead->prev = phead->next = phead;
    // 设置链表计数为0
    // count = 0;
}

// DoubleLink 析构函数
template<class T>
DoubleLink<T>::~DoubleLink()
{
    // 删除所有结点
    DNode<T>* ptmp;
    DNode<T>* pnode = phead->next;
    while (pnode != phead)
    {
        ptmp = pnode;
        pnode = pnode->next;
        delete ptmp;
    }
    
    // 删除表头
    delete phead;
    phead = NULL;
}

// 返回结点数目
template<class T>
int DoubleLink<T>::size()
{
    return count;    
}

// 返回链表是否为空
template<class T>
int DoubleLink<T>::is_empty()
{
    return count == 0;
}

// 获取第 index 位置的结点
template<class T>
DNode<T>* DoubleLink<T>::get_node(int index)
{
    // 判断有效性
    if (index < 0 || index >= count)
    {
        cout << "get node failed! the index in out of bound!" << endl;
        return NULL;
    }
    
    // 正向查找
    if (index <= count / 2)
    {
        int i = 0;
        DNode<T>* pindex = phead->next;
        while (i++ < index)
        {
            pindex = pindex->next;
        }
        
        return pindex;
    }
    
    
    // 反向查找
    int j = 0;
    int rindex = count - index - 1;
    DNode<T>* prindex = phead->prev;
    while (j++ < rindex)
    {
        prindex = prindex->prev;    
    }
    
    return prindex;
}

// 获取第index位置的结点的值
template<class T>
T DoubleLink<T>::get(int index)
{
    return get_node(index)->value;    
}

// 获取第1个结点的值
template<class T>
T DoubleLink<T>::get_first()
{
    return get_node(0)->value;    
}

// 获取最后一个结点的值
template<class T>
T DoubleLink<T>::get_last()
{
    return get_node(count - 1)->value;    
}

// 将结点插入到第index位置之前
template<class T>
int DoubleLink<T>::insert(int index, T t)
{
    if (index == 0)
        return insert_first(t);
    
    DNode<T>* pindex = get_node(index);
    if (!pindex) return -1;
    DNode<T>* pnode = new DNode<T>(t, pindex->prev, pindex);
    pindex->prev->next = pnode;
    pindex->prev = pnode;
    count++;
    
    return 0;
}

// 将结点插入第一个结点处
template<class T>
int DoubleLink<T>::insert_first(T t)
{
    DNode<T>* pnode = new DNode<T>(t, phead, phead->next);    
    phead->next->prev = pnode;
    phead->next = pnode;
    count++;
    
    return 0;
}

// 将结点追加到链表的末尾
template<class T>
int DoubleLink<T>::append_last(T t)
{
    DNode<T>* pnode = new DNode<T>(t, phead->prev, phead);
    phead->prev->next = pnode;
    phead->prev = pnode;
    count++;
    
    return 0;
}

// 删除index位置的结点
template<class T>
int DoubleLink<T>::del(int index)
{
    DNode<T>* pindex = get_node(index);
    pindex->next->prev = pindex->prev;
    pindex->prev->next = pindex->next;
    delete pindex;
    count--;
    
    return 0;
}

// 删除第一个结点
template<class T>
int DoubleLink<T>::delete_first()
{
    return del(0);
}

// 删除最后一个结点
template<class T>
int DoubleLink<T>::delete_last()
{
    return del(count - 1);    
}

// 双向链表操作int数据
/*
void int_test()
{
    
    
    DoubleLink<int>* pdlink = new DoubleLink<int>();
    
    pdlink->insert(0, 20); // 将 20 插入到第一个位置
    pdlink->append_last(10); // 将 10 追加到链表末尾
    pdlink->insert_first(30); // 将 30 插入到第一个位置
    
    pdlink->del(1);
    
    // 双向链表是否为空
    cout << "is_empty() = " << pdlink->is_empty() << endl;
    // 双向链表的大小
    cout << "size() = " << pdlink->size() << endl;
    
    // 打印双向链表中的数据
    int len = pdlink->size();
    for (int i = 0; i < len; i++)
    {
        cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;    
    }
}
*/


class Person
{
public:
    string name;
    int age;
public:
    Person() { }
    Person(string name, int age)
    {
        this->name = name;
        this->age = age;
    }
};

// 自定义数据类型
void person_test()
{
    Person p1("张一", 18);
    Person p2("张二", 20);
    Person p3("张三", 21);
    Person p4("张四", 22);
    
    DoubleLink<Person>* p = new DoubleLink<Person>(); 
    
    p->append_last(p1);
    p->append_last(p2);
    p->append_last(p3);
    p->append_last(p4);   
    
    int len = p->size();
    
    for (int i = 0; i < len; i++)
    {
        cout << "姓名:" << p->get(i).name << " 年龄:" << p->get(i).age << endl;
    }
    
    
}

int main()
{
    
    // int_test();

    person_test();

    return 0;
}
posted @ 2022-02-14 16:00  萨塔妮娅  阅读(84)  评论(0)    收藏  举报