异质链表可以包含派生于同一个基类的不同元素。首先我们看看主程序和运行结果:
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();
}
希望这种由简到繁的编程能够有所帮助。