异质链表

异质链表可以包含派生于同一个基类的不同元素。首先我们看看主程序和运行结果:

void main()
{
    Person ps1(0, "Tom", "19850615", 'M');
    Person ps2(0, "Jam", "19850637", 'M');
    Student st1(0, "Mike", "92876639", 'M', 100);
    Staff sf1(0, "Stephen", "00187740", 'M', 1002000);
    HeterList<Person> myList;
    //从尾部加入链表
    myList.Insert(&ps1);
    myList.Insert(&st1);
    myList.Insert(&sf1);
    //将元素插入指定位置
    myList.Insert(1, &ps2);
    myList.Print();
    //逐个删除
    myList.Delete();
    myList.Delete();
    myList.Print();
}

这里包含了两种插入方法以及异质链表,但是,我会讲得很简单
首先,我们不急着去实现异质链表,而是实现一个普通链表。链表的元素是Person类

class Person
{
public:
    Person(int id, string name = "", string birth = "", char sex = ' ')
        :m_identity(id), m_name(name), m_birth(birth), m_sex(sex)
    {}
    /*
    virtual void Print()
    将基本信息逐行打印
    */
    virtual void Print()
    {
        cout << "name: " << m_name << endl;
        cout << "id: " << m_identity << endl;
        cout << "birth: " << m_birth << endl;
        cout << "sex: " << m_sex << endl;
    }
protected:
    int m_identity;
    string m_name;
    string m_birth;
    //‘M’代表男性,‘F’代表女性
    char m_sex;
};

然后自己写一个链表,主要方法包括:Insert(), Delete(), Print()。这里使用了友元类的方法,方便链表对元素值直接读取。

/*********链表***********/

template<class Type> class HeterList;//declare before used as friend class

template<class Type>
class Node
{
    friend class HeterList<Type>;
public:
    Node() : m_data(NULL), m_next(NULL)
    {}
    Node(Type* data) : m_data(data), m_next(NULL)
    {}
    void Print()
    {
        m_data->Print();
    }
private:
    Type* m_data;
    Node<Type>* m_next;
};

/*
以代表元素的类为单位的链表
*/
template<class Type> 
class HeterList
{
public:
    HeterList() : m_length(0), m_current_pos(0)
    {
        Node<Type>* temp = new Node<Type>;//创建一个空元素节点
        m_current = m_head = m_tail = temp;
    }
    /*
    将元素从链表表尾插入
    */
    void Insert(Type* p_data)
    {
        Node<Type>* temp = new Node<Type>(p_data);
        m_tail->m_next = temp;
        m_tail = temp;
        m_length++;
        cout << "Insert to head..." << endl;
    }
    /*
    将一个元素从链表表头删除
    */
    void Delete()
    {
        if (!(m_tail->m_data))
        {
            cout << "Error: empty list..." << endl;
        }
        else
        {
            Node<Type>* temp = m_head;
            m_head = m_head->m_next;
            cout << "Deleting... " << endl;
            delete temp;
            m_length--;
        }
    }
    void Print()
    {
        if (!(m_tail->m_data))
        {
            cout << "Error: empty list..." << endl;
            return;
        }
        Node<Type> *tmp;
        for (tmp = m_head->m_next; tmp; tmp = tmp->m_next)
        {
            tmp->m_data->Print();
            cout << endl;
        }
    }
    int     m_length;
    Node<Type>* m_head;
    Node<Type>* m_tail;
};

注意,这里的Insert(Type* p_data)是将Person作为节点,而不是Node,具体请仔细看Node的定义。
在完成上述步骤,就可以运行如下的函数,检测基本的方法

void main()
{
    Person ps1(0, "Tom", "19850615", 'M');
    Person ps2(0, "Jam", "19850637", 'M');
    HeterList<Person> myList;
    //从尾部加入链表
    myList.Insert(&ps1);
    myList.Insert(&ps2);
    myList.Print();
    //逐个删除
    myList.Delete();
    myList.Delete();
    myList.Print();
}

好,完成了这一步,就开始做“异质”。其实很简单,就是做几个Person的派生类,注意Print()函数作为虚函数,实现多态性。

/*
class Student: public Person
*/
class Student : public Person
{
public:
    Student(int id, string name = "", string birth = "", char sex = ' ', int gpa = 0)
        :Person(id, name, birth, sex), m_gpa(gpa)
    {}
    void Print()
    {
        Person::Print();
        cout << "GPA: " << m_gpa << endl;
    }
private:
    int m_gpa;
};

/*
class Staff: public Person
*/
class Staff : public Person
{
public:
    Staff(int id, string name = "", string birth = "", char sex = ' ', int fund = 0)
        :Person(id, name, birth, sex), m_fund(fund)
    {}
    void Print()
    {
        Person::Print();
        cout << "Fund: " << m_fund << endl;
    }
private:
    int m_fund;
};

然后,主函数就可以写成:

void main()
{
    Person ps1(0, "Tom", "19850615", 'M');
    Person ps2(0, "Jam", "19850637", 'M');
    Student st1(0, "Mike", "92876639", 'M', 100);
    Staff sf1(0, "Stephen", "00187740", 'M', 1002000);
    HeterList<Person> myList;
    //从尾部加入链表
    myList.Insert(&ps1);
    myList.Insert(&st1);
    myList.Insert(&sf1);
    myList.Print();
    //逐个删除
    myList.Delete();
    myList.Delete();
    myList.Print();
}

最后,就是锦上添花,写了一个重载的插入函数Insert(int pos, Type* p_data),这部分可看可不看,仅仅是链表插入的实现。以下是完整代码

#ifndef HETER_LIST_H
#define HETER_LIST_H
#include <iostream>
#include <string>
#include <assert.h>

using namespace std;

//异质元素基类
/*
包含一个人的基本信息
*/
class Person
{
public:
    Person(int id, string name = "", string birth = "", char sex = ' ')
        :m_identity(id), m_name(name), m_birth(birth), m_sex(sex)
    {}
    /*
    virtual void Print()
    将基本信息逐行打印
    */
    virtual void Print()
    {
        cout << "name: " << m_name << endl;
        cout << "id: " << m_identity << endl;
        cout << "birth: " << m_birth << endl;
        cout << "sex: " << m_sex << endl;
    }
protected:
    int m_identity;
    string m_name;
    string m_birth;
    //‘M’代表男性,‘F’代表女性
    char m_sex;
};

/********异质元素派生类********/

/*
class Student: public Person
*/
class Student : public Person
{
public:
    Student(int id, string name = "", string birth = "", char sex = ' ', int gpa = 0)
        :Person(id, name, birth, sex), m_gpa(gpa)
    {}
    void Print()
    {
        Person::Print();
        cout << "GPA: " << m_gpa << endl;
    }
private:
    int m_gpa;
};

/*
class Staff: public Person
*/
class Staff : public Person
{
public:
    Staff(int id, string name = "", string birth = "", char sex = ' ', int fund = 0)
        :Person(id, name, birth, sex), m_fund(fund)
    {}
    void Print()
    {
        Person::Print();
        cout << "Fund: " << m_fund << endl;
    }
private:
    int m_fund;
};

/*********链表***********/

template<class Type> class HeterList;//declare before used as friend class

template<class Type>
class Node
{
    friend class HeterList<Type>;
public:
    Node() : m_data(NULL), m_next(NULL)
    {}
    Node(Type* data) : m_data(data), m_next(NULL)
    {}
    void Print()
    {
        m_data->Print();
    }
private:
    Type* m_data;
    Node<Type>* m_next;
};

/*
以代表元素的类为单位的链表
*/
template<class Type> 
class HeterList
{
public:
    HeterList() : m_length(0), m_current_pos(0)
    {
        Node<Type>* temp = new Node<Type>;//创建一个空元素节点
        m_current = m_head = m_tail = temp;
    }
    /*
    将元素从链表表尾插入
    */
    void Insert(Type* p_data)
    {
        Node<Type>* temp = new Node<Type>(p_data);
        m_tail->m_next = temp;
        m_tail = temp;
        m_length++;
        cout << "Insert to head..." << endl;
    }
    /*
    将元素插入到第pos个元素之后
    */
    void Insert(int pos, Type* p_data)
    {
        assert(pos < m_length);
        assert(pos > 0);
        Node<Type>* temp = new Node<Type>(p_data);
        //如果current超过了目标pos,重置current
        if (m_current_pos > pos)
        {
            ResetCurrent();
        }
        while (m_current_pos < pos)
        {
            TailwardCurrent();
        }
        //复制current的next指针
        temp->m_next = m_current->m_next;
        //重定位current指针
        m_current->m_next = temp;

        m_length++;
        cout << "Insert after" << pos << "th node..." << endl;
    }
    /*
    将一个元素从链表表头删除
    */
    void Delete()
    {
        if (!(m_tail->m_data))
        {
            cout << "Error: empty list..." << endl;
        }
        else
        {
            Node<Type>* temp = m_head;
            m_head = m_head->m_next;
            cout << "Deleting... " << endl;
            delete temp;
            m_length--;
        }
    }
    void Print()
    {
        if (!(m_tail->m_data))
        {
            cout << "Error: empty list..." << endl;
            return;
        }
        Node<Type> *tmp;
        for (tmp = m_head->m_next; tmp; tmp = tmp->m_next)
        {
            tmp->m_data->Print();
            cout << endl;
        }
    }
private:
    void TailwardCurrent()
    {
        m_current_pos++;
        assert(m_current_pos < m_length);
        m_current = m_current->m_next;
    }
    void ResetCurrent()
    {
        m_current = m_head;
        m_current_pos = 0;
    }
private:
    bool is_empty()
    {
        return m_head->m_next == m_tail;
    }
    int     m_length;
    Node<Type>* m_head;
    Node<Type>* m_tail;
    int m_current_pos;
    Node<Type>* m_current;
};

#endif
#include "heter_list.h"

void main()
{
    Person ps1(0, "Tom", "19850615", 'M');
    Person ps2(0, "Jam", "19850637", 'M');
    Student st1(0, "Mike", "92876639", 'M', 100);
    Staff sf1(0, "Stephen", "00187740", 'M', 1002000);
    HeterList<Person> myList;
    //从尾部加入链表
    myList.Insert(&ps1);
    myList.Insert(&st1);
    myList.Insert(&sf1);
    //将元素插入指定位置
    myList.Insert(1, &ps2);
    myList.Print();
    //逐个删除
    myList.Delete();
    myList.Delete();
    myList.Print();
}

希望这种由简到繁的编程能够有所帮助。

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值