链表的C++实现

使用C++实现自定义的链表

​

/*
 * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
 *
 * This file is part of ZLToolKit(https://github.com/xiongziliang/ZLToolKit).
 *
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
 */

#ifndef ZLTOOLKIT_LIST_H
#define ZLTOOLKIT_LIST_H

#include <type_traits>
using namespace std;

namespace toolkit {


template<typename T>
class List;

// 声明ListNode的节点
template<typename T>
class ListNode
{
public:
    friend class List<T>;
    ~ListNode(){}

    // 移动拷贝构造函数
    ListNode(T &&data):_data(std::forward<T>(data)){}

    // 拷贝构造函数
    ListNode(const T &data):_data(data){}

    template <class... Args>
    ListNode(Args&&... args):_data(std::forward<Args>(args)...){}
private:
    T _data;
    ListNode *next = nullptr;
};

// 声明List
template<typename T>
class List {
public:
    typedef ListNode<T> NodeType;
    List(){}
    List(List &&that){
        swap(that);
    }
    ~List(){
        clear();
    }
    void clear(){
        auto ptr = _front;
        auto last = ptr;
        while(ptr){
            last = ptr;
            ptr = ptr->next;
            delete last;
        }
        _size = 0;
        _front = nullptr;
        _back = nullptr;
    }
    template <typename  FUN>
    void for_each(FUN &&fun){
        auto ptr = _front;
        while(ptr){
            fun(ptr->_data);
            ptr = ptr->next;
        }
    }

    uint64_t size() const{
        return _size;
    }

    bool empty() const{
        return _size == 0;
    }

    // 在前面插入
    template <class... Args>
    void emplace_front(Args&&... args){
        NodeType *node = new NodeType(std::forward<Args>(args)...);
        if(!_front){
            _front = node;
            _back = node;
            _size = 1;
        }else{
            node->next = _front;
            _front = node;
            ++_size;
        }
    }

    // 在尾部插入
    template <class...Args>
    void emplace_back(Args&&... args){
        NodeType *node = new NodeType(std::forward<Args>(args)...);
        if(!_back){ // 尾部为Nullptr
            _back = node;
            _front = node;
            _size = 1;
        }else{
            _back->next = node;
            _back = node;
            ++_size;
        }
    }

    T &front() const{
        return _front->_data;
    }

    T &back() const{
        return _back->_data;
    }

    T &operator[](uint64_t pos){
        NodeType *front = _front ;
        while(pos--){
            front = front->next;
        }
        return front->_data;
    }

    void pop_front(){
        if(!_front){
            return;
        }
        auto ptr = _front;
        _front = _front->next;
        delete ptr;
        if(!_front){
            _back = nullptr;
        }
        --_size;
    }

    void swap(List &other){
        NodeType *tmp_node;

        tmp_node = _front;
        _front = other._front;
        other._front = tmp_node;

        tmp_node = _back;
        _back = other._back;
        other._back = tmp_node;

        uint64_t tmp_size = _size;
        _size = other._size;
        other._size = tmp_size;
    }

    void append(List<T> &other){
        if(other.empty()){
            return;
        }
        if(_back){
            _back->next = other._front;
            _back = other._back;
        }else{
            _front = other._front;
            _back = other._back;
        }
        _size += other._size;

        other._front = other._back = nullptr;
        other._size = 0;
    }
private:
    NodeType *_front = nullptr;
    NodeType *_back = nullptr;
    uint64_t _size = 0;
};

} /* namespace toolkit */
#endif //ZLTOOLKIT_LIST_H

[点击并拖拽以移动]
​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向对象程序设计课程作业 1. 请创建一个数据类型为T的链表类模板List,实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数,实现两个链表的赋值操作(10分) 7) operator+()函数,实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该类模板的正确性: 1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List类型的模板类对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List类型的模板类对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值