模板单向链表

希望大佬可以评论增加方法,修改问题

/*************************************************************************
    > File Name: singlelist.hpp
    > Author: hsz
    > Mail:
    > Created Time: 2021年03月28日 星期日 13时38分04秒
 ************************************************************************/

#ifndef __SINGLE_LIST_H__
#define __SINGLE_LIST_H__

#include <stdint.h>
#include <stddef.h>
#include <stdio.h>

namespace Alias {

/* 1、提供拷贝构造;2、重载 ==,<,> */
template <typename T>
struct Node {
    T *data;
    Node *next;

    Node() : data(nullptr), next(nullptr){}
    Node(const Node& v)
    {
        if (v.data) {
            data = new T(*(v.data)); // 无所谓空或不空,用时再检查
            if (data == nullptr) {
                // log
            }
        }
        next = nullptr;
    }

    Node &operator= (const Node &) = delete;
    ~Node()
    {
        if (data != nullptr) {
            delete data;
            data = nullptr;
        }
    }
};

template <typename T>
class SingleList {
public:
    typedef struct Node<T>  node_t;
    typedef struct Node<T>* nodeptr_t;
    
    SingleList()
    {
        mHeader = new node_t();
        if (mHeader == nullptr) {
            return;
        }
        
        mSize = 0;
        mListBack = mHeader;
    }
    SingleList(const SingleList& sl)
    {
        mHeader = new node_t();
        if (mHeader == nullptr) {
            printf("new error\n");
            return;
        }
        nodeptr_t pCurrent = sl.mHeader;
        nodeptr_t mpCurrent = mHeader;
        while (hasNext(pCurrent)) {
            nodeptr_t pNext = pCurrent->next;

            // Node 拷贝构造
            nodeptr_t node = new node_t(*pNext);
            mpCurrent->next = node;

            mpCurrent = mpCurrent->next;
            pCurrent = pNext;
        }
        mSize = sl.mSize;
        mListBack = mpCurrent;
    }

    SingleList &operator=(const SingleList& sl)
    {
        if(mHeader == nullptr) {
            mHeader = new node_t();
            if (mHeader == nullptr) {
                return *this;
            }
        }

        nodeptr_t pCurrent = sl.mHeader;
        nodeptr_t mpCurrent = mHeader;
        while (hasNext(pCurrent)) {
            nodeptr_t pNext = pCurrent->next;

            // Node 拷贝构造
            nodeptr_t node = new node_t(*pNext);
            mpCurrent->next = node;

            mpCurrent = mpCurrent->next;
            pCurrent = pNext;
        }
        mSize = sl.mSize;
        mListBack = mpCurrent;
    }

    ~SingleList()
    {
        printf("%s()\n", __func__);
        DestroyList();
    }

    // 头插
    void InsertFront(const T& t)
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t node = ConstructNode(t);
        if (node == nullptr) {
            return;
        }

        nodeptr_t pCurrent = mHeader->next;
        mHeader->next = node;
        node->next = pCurrent;

        ++mSize;
    }

    // 尾插
    void InsertBack(const T& t)
    {
        if (mHeader == nullptr) {
            return;
        }

        nodeptr_t node = ConstructNode(t);
        if (node == nullptr) {
            return;
        }

        mListBack->next = node;
        mListBack = node;

        ++mSize;
    }

    // 从第一个有效节点开始算为0
    void InsertByPos(const T& t, uint32_t pos = 0)
    {
        if (mHeader == nullptr) {
            return;
        }
        if (pos >= mSize) {
            InsertBack(t);
            return;
        }

        nodeptr_t node = ConstructNode(t);
        if (node == nullptr) {
            return;
        }

        nodeptr_t pCurrent = mHeader;
        for (size_t i = 0; (i < pos) && hasNext(pCurrent); ++i) {
            pCurrent = pCurrent->next;
        }
        nodeptr_t pNext = pCurrent->next;
        pCurrent->next = node;
        node->next = pNext;

        ++mSize;
    }

    void DeleteFront()
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t pCurrent = mHeader->next;
        nodeptr_t pNext = pCurrent->next;
        delete pCurrent;
        mHeader->next = pNext;
        --mSize;
    }

    void DeleteBack()
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t pCurrent = mHeader;
        nodeptr_t pDel = mHeader->next;
        while (hasNext(pDel)) {
            pCurrent = pCurrent->next;
            pDel = pDel->next;
        }
        pCurrent->next = pDel->next;
        delete pDel;
        pDel = nullptr;
        mListBack = pCurrent;
        --mSize;
    }

    void DeleteByData(const T &t)
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t pCurrent = mHeader;
        nodeptr_t pDel = mHeader->next;
        while (pDel) {
            if (*(pDel->data) == t) {
                pCurrent->next = pDel->next;
                if (pDel == mListBack) {
                    mListBack = pCurrent;
                }
                delete pDel;
                pDel = nullptr;
                --mSize;
                return;
            }
            pCurrent = pCurrent->next;
            pDel = pDel->next;
        }
    }

    /**
     * @param forword del前一个节点
     * @param del     你想删除的节点
     */
    void DeleteByNode(const nodeptr_t forword, const nodeptr_t del)
    {
        if (mHeader == nullptr || !forword || !del) {
            return;
        }
        if (forword->next != del) {
            return;
        }
        forword->next = del->next;
        if (del == mListBack) {     // 删除的正好是最后一个节点
            mListBack = forword;
        }
        delete del;
        --mSize;
    }

    void ClearList()
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t pCurrent = mHeader->next;
        while (pCurrent) {
            nodeptr_t pNext = pCurrent->next;
            delete pCurrent;

            pCurrent = pNext;
        }
        mHeader->next = nullptr;
        mSize = 0;
        mListBack = mHeader;
    }

    void DestroyList()
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t pCurrent = mHeader;
        while (pCurrent) {
            nodeptr_t pNext = pCurrent->next;
            delete pCurrent;

            pCurrent = pNext;
        }
        mHeader = nullptr;
        mSize = 0;
        mListBack = nullptr;
    }

    void ForeachList(void (*CallBack)(void *))
    {
        if (mHeader == nullptr) {
            return;
        }
        nodeptr_t pCurrent = mHeader;
        while (hasNext(pCurrent)) {
            nodeptr_t pNext = pCurrent->next;
            if (pNext != nullptr) {
                CallBack(static_cast<void *>(pNext->data));
                pCurrent = pNext;
            }
        }
    }

    bool isValidList() const
    {
        return !!mHeader;
    }

    uint32_t getSize() const
    {
        return mSize;
    }
    nodeptr_t getLastOne() const
    {
        return mListBack;
    }
    nodeptr_t getHeader() const
    {
        return mHeader;
    }

    bool hasNext(const nodeptr_t n) const
    {
        if (n == nullptr) {
            return false;
        }
        return !!(n->next);
    }

private:
    nodeptr_t ConstructNode(const T &t) const
    {
        T *temp = new T(t);
        if (temp == nullptr) {
            return nullptr;
        }
        nodeptr_t node = new node_t();
        if (node == nullptr) {
            delete temp;
            return nullptr;
        }
        node->data = temp;
        return node;
    }
private:
    nodeptr_t mHeader;
    uint32_t  mSize;
    nodeptr_t mListBack;
};

} // namespace Alias
#endif

测试用例

/*************************************************************************
    > File Name: testlist.cpp
    > Author: hsz
    > Mail:
    > Created Time: 2021年03月28日 星期日 13时54分22秒
 ************************************************************************/

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

void print(void *data)
{
    const int *num = static_cast<int *>(data);
    cout << *num << endl;
}

int main(int argc, char **argv)
{
    Alias::SingleList<int> sl;
    sl.InsertBack(10);
    sl.InsertBack(20);
    sl.InsertBack(30);
    sl.InsertBack(40);

    sl.InsertFront(0);
    sl.DeleteFront();
    sl.DeleteBack();
    sl.DeleteByData(30);
    sl.ForeachList(print);
    cout << "*********************\n";
    cout << "list size = " << sl.getSize() << endl;
    sl.ClearList();
    sl.ForeachList(print);
    cout << "*********************\n";
    cout << "list size = " << sl.getSize() << endl;
    sl.DestroyList();
    cout << "*********************\n";
    cout << "list size = " << sl.getSize() << endl;
    return 0;
}

暂时未提供排序功能,后续改进
接下来实现string类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值