C++(3)_异质链表

终于考完了万恶的期末考,有时间把落下的blog更一下

异质链表

异质链表means链表内节点类型可以不是同一种。
下面放上课程作业(一个小型的学校信息管理系统)中成员类型定义的.h文件。
其中有一个抽象节点(Node)基类Person类,其它类都在此基础上继承;
故在链表(HeterList)类中,定义链表头指针时,只需要将头指针定义为基类类型即可通过该头指针指向其继承类。

#include <iostream>
#include <string>

using namespace std;

//友元类需要事先声明
class HeterList;

/*
*节点类,各类class的定义
*/
//抽象基类 Person
class Person
{
    friend class HeterList;

public:
    //构造函数
    //Person():_name(""),_sex('M'),_age(0),_IDnumber(""),_next(NULL){}

    Person(char *name, char sex, int age, char *IDnumber)
    :_sex(sex),_age(age),_next(NULL)
    {
        strcpy_s(Person::_name, name);
        strcpy_s(Person::_IDnumber, IDnumber);
    }


    //纯虚函数
    virtual void addNode() = 0;     //将对象添加进链表,变成一个节点
    virtual void display() = 0;     //显示信息

    //析构函数
    ~Person() {}

//希望与派生类分享,但不想被其他公共访问的成员
protected:
    char _name[20];
    char _sex;
    int _age;
    char _IDnumber[20];

    static Person *_ptr;    //定义一个指向Person类对象的静态指针
    Person *_next;          //指向下一个节点的指针
};

//教师类
class Teacher:public Person
{
    friend class HeterList;

public:
    //构造函数
    //Teacher():Person(),_fund(0),_major(""),_salary(0){}

    Teacher(char *name, char sex, int age, char *IDnumber, int fund, char *major, int salary)
        :Person(name, sex, age, IDnumber),_fund(fund),_salary(salary)
        {
            strcpy_s(Teacher::_major, major);
        }


    //重写将对象添加进链表函数
    void addNode()
    {
        _ptr = new Teacher(_name, _sex, _age, _IDnumber, _fund, _major, _salary);
    }

    //重写信息显示函数
    void display()
    {
        cout<<"Name:"<<_name<<endl;
        cout<<"Sex:"<<_sex<<endl;
        cout<<"Age:"<<_age<<endl;
        cout<<"ID NUmber:"<<_IDnumber<<endl;
        cout<<"Job: Teacher"<<endl;
        cout<<"Fund:"<<_fund<<endl;
        cout<<"Major:"<<_major<<endl;
        cout<<"Salary:"<<_salary<<endl;
        cout<<endl;
    }

    //析构函数
    ~Teacher() {}

private:
    int _fund;
    char _major[20];
    int _salary;
};

//职工类
class Stuff:public Person
{
    friend class HeterList;

public:
    //构造函数
    //Stuff():Person(),_department(""),_position(""),_salary(0){}

    Stuff(char *name, char sex, int age, char *IDnumber, char *department, char *position, int salary)
        :Person(name, sex, age, IDnumber),_salary(salary)
    {
        strcpy_s(Stuff::_department, department);
        strcpy_s(Stuff::_position, position);
    }

    void display()
    {
        cout<<"Name:"<<_name<<endl;
        cout<<"Sex:"<<_sex<<endl;
        cout<<"Age:"<<_age<<endl;
        cout<<"ID NUmber:"<<_IDnumber<<endl;
        cout<<"Job: Stuff"<<endl;
        cout<<"Department:"<<_department<<endl;
        cout<<"Position:"<<_position<<endl;
        cout<<"Salary:"<<_salary<<endl;
        cout<<endl;
    }

    //重写将对象添加进链表函数
    void addNode()
    {
        _ptr = new Stuff(_name, _sex, _age, _IDnumber, _department, _position, _salary);
    }

    //析构函数
    ~Stuff() {}

private:
    char _department[20];
    char _position[20];
    int _salary;
};

//本科生类
class Undergraduate:public Person
{
    friend class HeterList;

public:
    //构造函数
    //Undergraduate():Person(),_gradePoint(0){}

    Undergraduate(char *name, char sex, int age, char *IDnumber, int gradePoint)
        :Person(name, sex, age, IDnumber),_gradePoint(gradePoint){}

    void display()
    {
        cout<<"Name:"<<_name<<endl;
        cout<<"Sex:"<<_sex<<endl;
        cout<<"Age:"<<_age<<endl;
        cout<<"ID NUmber:"<<_IDnumber<<endl;
        cout<<"Job: Undergraduate"<<endl;
        cout<<"GradePoint:"<<_gradePoint<<endl;
        cout<<endl;
    }

    //重写将对象添加进链表函数
    void addNode()
    {
        _ptr = new Undergraduate(_name, _sex, _age, _IDnumber, _gradePoint);
    }

    //析构函数
    ~Undergraduate() {}

//希望与派生类分享,但不想被其他公共访问的成员
protected:
    int _gradePoint;
};

//全日制研究生类
class FulltimePostgraduate:public Undergraduate
{
    friend class HeterList;
    //friend class Teacher;

public:
    //构造函数
    //FulltimePostgraduate():Undergraduate(),_major(""),_tutor(""){}

    FulltimePostgraduate(char *name, char sex, int age, char *IDnumber, int gradePoint, char *major, char *tutor)
        :Undergraduate(name, sex, age, IDnumber, gradePoint)
    {
        strcpy_s(FulltimePostgraduate::_major, major);
        strcpy_s(FulltimePostgraduate::_tutor, tutor);
    }

    void display()
    {
        cout<<"Name:"<<_name<<endl;
        cout<<"Sex:"<<_sex<<endl;
        cout<<"Age:"<<_age<<endl;
        cout<<"ID NUmber:"<<_IDnumber<<endl;
        cout<<"Job: FulltimePostgraduate"<<endl;
        cout<<"GradePoint:"<<_gradePoint<<endl;
        cout<<"Major:"<<_major<<endl;
        cout<<"Tutor:"<<_tutor<<endl;
        cout<<endl;
    }

    //重写将对象添加进链表函数
    void addNode()
    {
        _ptr = new FulltimePostgraduate(_name, _sex, _age, _IDnumber, _gradePoint, _major, _tutor);
    }

    //析构函数
    ~FulltimePostgraduate() {}


//希望与派生类分享,但不想被其他公共访问的成员
protected:
    char _major[20];
    char _tutor[20];
};

//在职研究生类
class OnthejobPostgraduate:public FulltimePostgraduate
{
    friend class HeterList;

public:
    //构造函数
    //OnthejobPostgraduate():FulltimePostgraduate(),_salary(0){}

    OnthejobPostgraduate(char *name, char sex, int age, char *IDnumber, int gradePoint, char *major, char *tutor, int salary)
        :FulltimePostgraduate(name, sex, age, IDnumber, gradePoint, major, tutor),_salary(salary){}

    void display()
    {
        cout<<"Name:"<<_name<<endl;
        cout<<"Sex:"<<_sex<<endl;
        cout<<"Age:"<<_age<<endl;
        cout<<"ID NUmber:"<<_IDnumber<<endl;
        cout<<"Job: FulltimePostgraduate"<<endl;
        cout<<"GradePoint:"<<_gradePoint<<endl;
        cout<<"Major:"<<_major<<endl;
        cout<<"Tutor:"<<_tutor<<endl;
        cout<<"Salary:"<<_salary<<endl;
        cout<<endl;
    }

    //重写将对象添加进链表函数
    void addNode()
    {
        _ptr = new OnthejobPostgraduate(_name, _sex, _age, _IDnumber, _gradePoint, _major, _tutor, _salary);
    }

    //析构函数
    ~OnthejobPostgraduate() {}

//希望与派生类分享,但不想被其他公共访问的成员
protected:
    int _salary;
}; 




//异质链表类
class HeterList
{
public:
    //构造函数
    HeterList():Root(NULL){}

    void InsertNode(Person *node);  //以基类指针为参数,可以接收所有派生类对象的指针
    void SearchNode(char *name);
    void DeleteNode(char *name);
    void UpdateNode(char *name);
    void displayList(); //待改

    //析构函数
    ~HeterList() {}

private:
    Person *Root;   //定义链表头指针
};

void HeterList::InsertNode(Person *node)
{
    //定义两个查找指针
    Person *curr = Root;    //指向当前节点的指针,从Root开始
    Person *prev = NULL;    //指向前一个节点的指针

    //移到链表的最后一个节点
    //如果当前链表没有节点,则curr=Root=NULL
    while( curr != NULL )
    {
        //往后一个节点
        prev = curr;
        curr = curr->_next;
    }

    node->addNode();//有了指向当前对象的指针ptr
    node->_ptr->_next = curr; //插在最后一个前面
    if(prev==NULL)  //当前链表没有节点
    {
        Root = node->_ptr;
    }
    else
    {
        prev->_next = node->_ptr;   
    }

}

void HeterList::SearchNode(char *name)
{
    Person *curr = Root;    //指向当前节点的指针,指向根节点

    while( (curr!=NULL) && (strcmp(curr->_name, name) !=0) )
    {//找到了跳出,或者到头了跳出
        curr = curr->_next;
    }
    if( curr == NULL )
    {//没找到
        cout<<"Can't find this member, please check it again!"<<endl;
    }
    else 
    {
        curr->display();
    }
}

void HeterList::DeleteNode(char *name)
{
    Person *curr = Root;    //指向当前节点的指针,指向根节点
    Person *prev = NULL;    //指向前一个节点的指针

    while( (curr!=NULL) && (strcmp(curr->_name, name) !=0) )
    {//找到了跳出,或者到头了跳出
        prev = curr;
        curr = curr->_next;
    }
    if( (prev==NULL) && (curr!=NULL) )
    {//curr指向的第一个就是,把Root移动
        Root = curr->_next;
        delete curr;
    }
    else if( (prev!=NULL) && (curr!=NULL) )
    {//不是第一个
        prev->_next = curr->_next;
        delete curr;
    }
}

void HeterList::UpdateNode(char *name)
{
    Person *curr = Root;    //指向当前节点的指针,指向根节点
    Person *prev = NULL;    //指向前一个节点的指针

    while( (curr!=NULL) && (strcmp(curr->_name, name) !=0) )
    {//找到了跳出,或者到头了跳出
        prev = curr;
        curr = curr->_next;
    }
    if( curr == NULL )
    {//没找到
        cout<<"Can't find this member, please check it again!"<<endl;
    }
    else
    {//找到了

    }
}

void HeterList::displayList()
{
    Person *curr = Root;
    while(curr != NULL)
    {
        curr->display();
        curr = curr->_next;
    }
}
  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
[入门数据分析的第一堂课]这是一门为数据分析小白量身打造的课程,你从网络或者公众号收集到很多关于数据分析的知识,但是它们零散不成体系,所以第一堂课首要目标是为你介绍:Ø  什么是数据分析-知其然才知其所以然Ø  为什么要学数据分析-有目标才有动力Ø  数据分析的学习路线-有方向走得更快Ø  数据分析的模型-分析之道,快速形成分析思路Ø  应用案例及场景-分析之术,掌握分析方法[哪些同学适合学习这门课程]想要转行做数据分析师的,零基础亦可工作中需要数据分析技能的,例如运营、产品等对数据分析感兴趣,想要更多了解的[你的收获]n  会为你介绍数据分析的基本情况,为你展现数据分析的全貌。让你清楚知道自己该如何在数据分析地图上行走n  会为你介绍数据分析的分析方法和模型。这部分是讲数据分析的道,只有学会底层逻辑,能够在面对问题时有自己的想法,才能够下一步采取行动n  会为你介绍数据分析的数据处理和常用分析方法。这篇是讲数据分析的术,先有道,后而用术来实现你的想法,得出最终的结论。n  会为你介绍数据分析的应用。学到这里,你对数据分析已经有了初步的认识,并通过一些案例为你展现真实的应用。[专享增值服务]1:一对一答疑         关于课程问题可以通过微信直接询问老师,获得老师的一对一答疑2:转行问题解答         在转行的过程中的相关问题都可以询问老师,可获得一对一咨询机会3:打包资料分享         15本数据分析相关的电子书,一次获得终身学习
C++中实现异质链表的常用方法是使用多态性。具体而言,我们可以定义一个基类 `Node`,然后派生出不同的子类,每个子类表示不同类型的节点。例如: ```cpp class Node { public: virtual ~Node() {} }; class IntNode : public Node { public: IntNode(int val) : value(val) {} int value; }; class StringNode : public Node { public: StringNode(const std::string& str) : value(str) {} std::string value; }; ``` 然后,我们可以定义一个链表节点 `LinkedListNode`,它包含一个指向基类 `Node` 的指针。这样,我们就可以将不同类型的节点放入链表中。 ```cpp class LinkedListNode { public: LinkedListNode(Node* n) : node(n), next(nullptr) {} Node* node; LinkedListNode* next; }; ``` 对于链表的构造,我们可以定义一个 `LinkedList` 类,并提供相应的操作: ```cpp class LinkedList { public: ~LinkedList() { LinkedListNode* cur = head; while (cur) { LinkedListNode* next = cur->next; delete cur->node; // 释放节点占用的内存 delete cur; cur = next; } } void addNode(Node* n) { LinkedListNode* newNode = new LinkedListNode(n); if (!head) { head = newNode; } else { LinkedListNode* cur = head; while (cur->next) { cur = cur->next; } cur->next = newNode; } } private: LinkedListNode* head = nullptr; }; ``` 这样,我们就可以像下面这样构造异质链表: ```cpp LinkedList list; list.addNode(new IntNode(42)); list.addNode(new StringNode("hello")); ``` 注意,由于基类 `Node` 包含虚析构函数,因此我们可以通过 `delete` 删除派生类对象,从而正确地释放内存。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值