C++单向链表之三

单向链表

使用虚头结点、结构体、接口(即多态)、类模板实现 单向链表

1.加入 虚头节点 同一 增删 代码逻辑,如图:

在这里插入图片描述
2. 自定义数据元素为 struct 结构体,定义、使用、返回、并显示自定义的数据类型:

typedef struct data{
    std::string name;
    int age;
    std::string sex;
    float salary;

    data(std::string name="", int age=0, std::string sex="", float salary=0.00){
        this->name = std::move(name);
        this->age = age;
        this->sex = std::move(sex);
        this->salary = salary;
    }

} Data;

注意:
在结构体中引入了 结构体的构造函数,并赋初始值,这样在创建数据的时候不初始化,会使用结构体构造函数默认初始化,也可以通过类型初始化,如:

//    Data data1;	// 默认初始化
//    Data data1=Data();	// 通过 数据类型 默认初始化
    Data data1=Data("Gavin", 18,  "man", 30000.00);
//    Data data1("Gavin", 18,  "man", 30000.00);
    cout << data1.name << "\t" << data1.age << "\t" << data1.sex << "\t" << data1.salary << endl;

3.多态
定义父类 virtual 成员函数, 子类重写父类虚方法,调用时:定义父类实例,使父类指向子类方法,
注意:虚方法可以没有具体的实现逻辑,但是要有实现。
在这里插入图片描述

4.定义节点:
TData,就是自定义的 Data 数据类型,TData是模板类型名:template <classs TData>

typedef struct node{
            TData Elements;
            node * next;
            // 结构体--->构造函数
            node(TData Elements= TData(), node* next= nullptr){
                this->Elements = Elements;
                this->next = next;
            }
        } Node;

5.代码:
以 模板类 的方式实现的:linkedList.h

#ifndef SIMPLY_LINKEDLIST_LINKEDLIST_STRUCT_H
#define SIMPLY_LINKEDLIST_LINKEDLIST_STRUCT_H
#include <iostream>
#include <utility>

template <typename T>
class Interface{
    /* 全部为虚函数*/
    public:
        virtual ~Interface();

        virtual int size() const;
        virtual void clear();
        virtual bool contains(T& element);
        virtual void add(T& element);
        virtual void add(T& element, int index);
        virtual T get(int index) const;
        virtual T set(T& element, int index);
        virtual T remove(int index);
        virtual int getPos(T& element);
        virtual void display() const;
        virtual bool equals(T& elems1, T& elems2);
        virtual void displaySingleData(const T& tData) const;
};

// 虚函数---> 必须要给出 实现代码(没有具体的实现功能),即便子类已经重写了父类的成员函数;纯虚函数,可以没有实现代码。
template<typename T>
int Interface<T>::size() const {
    return 0;
}

template<typename T>
void Interface<T>::clear() {

}

template<typename T>
bool Interface<T>::contains(T &element) {
    return false;
}

template<typename T>
void Interface<T>::add(T &element) {

}

template<typename T>
void Interface<T>::add(T &element, int index) {

}

template<typename T>
T Interface<T>::get(int index) const {
    return T();
}

template<typename T>
T Interface<T>::set(T &element, int index) {
    return T();
}

template<typename T>
T Interface<T>::remove(int index) {
    return T();
}

template<typename T>
int Interface<T>::getPos(T &element) {
    return 0;
}

template<typename T>
void Interface<T>::display() const {

}

template<typename T>
bool Interface<T>::equals(T &elems1, T &elems2) {
    return false;
}

template<typename T>
void Interface<T>::displaySingleData(const T &tData) const {

}

template <typename T>
Interface<T>::~Interface() = default;

// 下面代码为: 子类的具体实现
template <class TData>
class LinkedList_struct : public Interface<TData>{

    private:
        const int NOT_FOUND = -1;
        int Size;

        typedef struct node{
            TData Elements;
            node * next;
            // 结构体--->构造函数
            node(TData Elements= TData(), node* next= nullptr){
                this->Elements = Elements;
                this->next = next;
            }
        } Node;

        Node* first;

        Node* node(int index) const{
            Node* nd = first->next;
            for(int i=0; i<index; ++i){
                nd = nd->next;
            }
            return nd;
        }

    public:
        LinkedList_struct();
        LinkedList_struct(TData& data, Node* next);
        ~LinkedList_struct();

        int size() const override;
        void clear() override;
        bool contains(TData& element);
        void add(TData& element);
        void add(TData& element, int index);
        TData get(int index) const;
        TData set(TData& element, int index);
        TData remove(int index) ;
        int getPos(TData& element);
        bool equals(TData& tData1, TData& tData2);
        void display() const;
        void displaySingleData(const TData& tData) const;

};

    template <class TData>
    LinkedList_struct<TData>::LinkedList_struct():Size(0){
        first = new Node();
    }

    template <class TData>
    LinkedList_struct<TData>::LinkedList_struct(TData &data, Node* next):Size(0), Node(data, next){
        first = new Node();
    }

    template <class TData>
    LinkedList_struct<TData>::~LinkedList_struct(){
        clear();
    }

    template <class TData>
    int LinkedList_struct<TData>::size() const{
        return Size;
    }

    template <class TData>
    void LinkedList_struct<TData>::clear(){
        Node* node = first;
        int cnt = 0;
        while(node != nullptr){
            auto q = node->next;
            delete node;
            node = q;
            ++cnt;
        }
        Size = 0;
        first = nullptr;    // 虽然 first 指向的内存被释放了,但是 first 的值并不为空,会导致析构函数死循环或错误退出。
        std::cout << "...calling destructor...cnt--->" << cnt << std::endl;
    }

    template <class TData>
    bool LinkedList_struct<TData>::contains(TData &element) {
        return getPos(element) != NOT_FOUND;
    }

    template <class TData>
    void LinkedList_struct<TData>::add(TData& element) {
        add(element, Size);
    }

    template <class TData>
    void LinkedList_struct<TData>::add(TData& element, int index) {
        Node* prev = index==0? first:node(index-1);
        prev->next = new Node(element, prev->next);
        ++Size;
    }

    template <class TData>
    TData LinkedList_struct<TData>::remove(int index) {
        Node* prev = index==0? first:node(index-1);
        auto old = prev->next;
        prev->next = old->next;
        TData oldE = old->Elements;
        --Size;
        return oldE;
    }

    template <class TData>
    TData LinkedList_struct<TData>::get(int index) const {
        return node(index)->Elements;
    }

    template <class TData>
    TData LinkedList_struct<TData>::set(TData& element, int index) {
        auto ptr = node(index);
        TData old = ptr->Elements;
        ptr->Elements = element;
        return old;
    }

    template <class TData>
    int LinkedList_struct<TData>::getPos(TData &element) {
        Node * ptr = first->next;
        int pos = NOT_FOUND;
        for (int i=0; i < Size; ++i){
            if(equals(element,ptr->Elements)){
                pos = i;
                break;
            }
            ptr = ptr->next;
        }
        return pos;
    }

    template <class TData>
    bool LinkedList_struct<TData>::equals(TData &tData, TData &elems2) {
        if (tData.name == elems2.name && tData.age == elems2.age && tData.sex == elems2.sex && tData.salary == elems2.salary){
            return true;
        }else{
            return false;
        }
    }

    template <class TData>
    void LinkedList_struct<TData>::display() const {
        Node* nd = first->next;
        std::cout << "name:\t" << "age:\t" << "sex:\t" << "salary:\t" << std::endl;
        for (int i=0; i<Size; ++i){
            std::cout << nd->Elements.name << "\t" << nd->Elements.age << "\t" << nd->Elements.sex << "\t"
            << nd->Elements.salary << std::endl;
            nd = nd->next;
        }

    }

    template <class TData>
    void LinkedList_struct<TData>::displaySingleData(const TData& tData) const {
        std::cout << tData.name << "\t" << tData.age << "\t" << tData.sex << "\t" << tData.salary << std::endl;
    }

#endif //SIMPLY_LINKEDLIST_LINKEDLIST_STRUCT_H

测试代码

#include <iostream>
#include <utility>
#include "linkedList.h"

using std::cout;
using std::endl;

typedef struct data{
    std::string name;
    int age;
    std::string sex;
    float salary;

    data(std::string name="", int age=0, std::string sex="", float salary=0.00){
        this->name = std::move(name);
        this->age = age;
        this->sex = std::move(sex);
        this->salary = salary;
    }

} Data;



int main(){

//    Data data1;
//    Data data1=Data();
    Data data1=Data("Gavin", 18,  "man", 30000.00);
//    Data data1("Gavin", 18,  "man", 30000.00);
    cout << data1.name << "\t" << data1.age << "\t" << data1.sex << "\t" << data1.salary << endl;

    cout << "---------------------------------------------------------------------" << endl;
    cout << "---------------------------------------------------------------------" << endl;
    Data data2("Evans", 20, "man", 25000);
    Data data3("lucy", 25, "girls", 25000);
    Data data4("lily", 30, "woman", 2500);
    Data data5("Lydia", 28, "man", 65000);
    Data data6("sally", 22, "girls", 95000);
    Data data7("sam", 27, "man", 150000);
    Data data8("Ailsa", 28, "girls", 200000);
    Data data9("edison", 32, "man", 300000);

    Interface<Data>* lst = new LinkedList_struct<Data>();
//    auto lst = new LinkedList_struct<Data>();

    // function--->add()
    lst->add(data1, 0);
    lst->add(data2);
    lst->add(data3, lst->size());
    lst->add(data4);
    lst->add(data5);
    lst->add(data6, 3);
    lst->add(data7);
    lst->add(data8);
    lst->add(data9);

    lst->display();
    cout << "---------------------------------------------------------------------" << endl;

    // function--->remove()
    lst->remove(0);                 // 删除 第一个 节点
    lst->remove(lst->size()-1);     // 删除最后一个 节点
    Data tData = lst->remove(3);    // 删除 索引为 3 的节点
    lst->displaySingleData(tData);
    cout << endl;
    lst->display();
    cout << "---------------------------------------------------------------------" << endl;

    // function--->set()
    Data data10("Aaron", 23, "man", 631452);
    tData = lst->set(data10, 3);
    lst->displaySingleData(tData);
    cout << endl;
    lst->display();
    cout << "---------------------------------------------------------------------" << endl;

    // function--->get()
    tData = lst->get(5);
    lst->displaySingleData(tData);
    cout << "---------------------------------------------------------------------" << endl;

    // function--->getPos()
    int pos = lst->getPos(data8);
    cout << "pos: " << pos << endl;
    // data9 被删除了,试着 获取看是否存在?
    pos = lst->getPos(data9);
    cout << "pos: " << pos << endl;
    cout << "---------------------------------------------------------------------" << endl;

    //function--->contains()
    bool res = lst->contains(data9);
    cout << "result: " << res << endl;
    res = lst->contains(data2);
    cout << "result: " << res << endl;
    cout << "---------------------------------------------------------------------" << endl;

    delete lst;

    return 0;
}

运行结果:

E:\programme\C_C++\CLion\C++\algorithm\LinkedList\simply_LinkedList\cmake-build-debug\simply_LinkedList.exe
Gavin   18      man     30000
---------------------------------------------------------------------
---------------------------------------------------------------------
name:   age:    sex:    salary:
Gavin   18      man     30000
Evans   20      man     25000
lucy    25      girls   25000
sally   22      girls   95000
lily    30      woman   2500
Lydia   28      man     65000
sam     27      man     150000
Ailsa   28      girls   200000
edison  32      man     300000
---------------------------------------------------------------------
lily    30      woman   2500

name:   age:    sex:    salary:
Evans   20      man     25000
lucy    25      girls   25000
sally   22      girls   95000
Lydia   28      man     65000
sam     27      man     150000
Ailsa   28      girls   200000
---------------------------------------------------------------------
Lydia   28      man     65000

name:   age:    sex:    salary:
Evans   20      man     25000
lucy    25      girls   25000
sally   22      girls   95000
Aaron   23      man     631452
sam     27      man     150000
Ailsa   28      girls   200000
---------------------------------------------------------------------
Ailsa   28      girls   200000
---------------------------------------------------------------------
pos: 5
pos: -1
---------------------------------------------------------------------
result: 0
result: 1
---------------------------------------------------------------------
...calling destructor...cnt--->7

Process finished with exit code 0

注意:
1.共创建了 9 个 Data 结构体数据,调用 remove() 时,删除了 3 个,剩余 6 个节点存储数据
2.最后调用析构函数 7 次:因为 要析构 6个数据节点 + 1个虚头节点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值