异质链表的实现

一、目标

实现一个链表,其中的元素类型可以不同。


 

二、思路

【思路一】

在结点中用共用体保存数据,用void*指针指向下一个结点,并且在结点中记录本结点的数据类型。

0000    enum Type {INT, CHAR, STRING};
0001    struct Node{
0002           Type NodeType;
0003           union {
0004                  int intData;
0005                  char charData;
0006                  string strData;
0007           }value;
0008           void *next;
0009    };

链表的每一个元素其实还都是一样的

【思路二】

设计一个抽象结点类,不同数据类型的结点来继承它。用基类的指针可以指向每一个派生类。




【思路三】

上面两种思路都要求数据类型已知,难以添加新的类型。于是把【思路二】略修改一下,用模板写了派生类。



三、代码

0000    #ifndef HETERLIST_H
0001    #define HETERLIST_H
0002    #include <iostream>
0003    #include <list>
0004    
0005    struct Pointer{
0006        //用于遍历时打印结点数据
0007        virtual std::ostream& printData(std::ostream&)=0;
0008        //用于搜索时判断两结点是否相等
0009        virtual bool operator ==(Pointer*)=0;
0010    };
0011    
0012    template<typename T>
0013    class Node : public Pointer {
0014        T _data;
0015    public:
0016        Node():_data(0){}
0017        Node(T data):_data(data){}
0018        virtual std::ostream& printData(std::ostream& out)
0019                {out << _data;return out;}
0020        virtual bool operator == (Pointer* p)
0021        {
0022            if (Node<T>* pp=dynamic_cast<Node<T>*>(p))
0023                return _data==pp->getData();
0024            else
0025                return false;
0026        }
0027        const T getData() const{return _data;}
0028        void setData(T d){data=d;}
0029        virtual ~Node(){};
0030    };
0031    
0032    std::ostream& operator << (std::ostream& out, Pointer* p)
0033    {
0034        return p->printData(out);
0035    }
0036    
0037    
0038    typedef std::list<Pointer*> HeterList;
0039    typedef std::list<Pointer*>::iterator HLI;
0040    
0041    #endif // HETERLIST_H


0000    #include <iostream>
0001    #include <string>
0002    #include <cstdlib>
0003    #include "HeterList.h"
0004    using namespace std;
0005    
0006    //自定义一个简单的类,用于测试本异质链表是否可以插入自定义类
0007    //从异质链表的定义可见,要求自定义类重载operator <<和==
0008    class classNode{
0009        string _str;
0010    public:
0011        classNode(string s=0):_str(s){}
0012        string getData()const {return _str;}
0013        ostream& printData(ostream& out){out<< _str;return out;}
0014        bool operator == (classNode n){return _str==n.getData();}
0015    };
0016    //避免用友元,保持类的封装性
0017    ostream& operator << (ostream& out, classNode* n)
0018    {
0019        return n->printData(out);
0020    }
0021    
0022    int main()
0023    {
0024        //定义一个异质链表testList
0025        HeterList testList;
0026        //为了测试,定义了三种不同“质”的结点。实际上由于用了template,
0027        //本异质链表可以插入任意类型的结点。但有个前提条件:如果是类
0028        //的话,这个类要求重载operator <<和==
0029        Node<int>* intNode;
0030        Node<char>* charNode;
0031        Node<classNode*>* userNode;
0032    
0033        classNode* tempClassNode;
0034    
0035        //插入int型元素
0036        for (int i = 0; i< 3; ++i){
0037            intNode = new Node<int>(i);
0038            testList.push_back(intNode);
0039        }
0040        //插入char型元素
0041        for (char c = 'a'; c< 'c'+1; ++c){
0042            charNode = new Node<char>(c);
0043            testList.push_back(charNode);
0044        }
0045    
0046        //插入自定义类
0047        for (int i = 0; i< 3; ++i){
0048            string s = "My class ";
0049            s += char(i+48); //'0'的ACII码是48
0050            tempClassNode=new classNode(s);
0051            userNode = new Node<classNode*>(tempClassNode);
0052        testList.push_back(userNode);
0053        }
0054    
0055        cout << "遍历链表:" <<endl;
0056        for (HLI i = testList.begin(); i!=testList.end(); ++i){
0057            cout << *i << endl;
0058        }
0059        //销毁异质链表。注意:如果链表元素是自定义类指针,先要销毁该指针
0060        //所指向的对象
0061        cout << "销毁链表:" <<endl;
0062        int j=0;
0063        for (HLI i = testList.begin(); i!=testList.end(); ++i,++j){
0064            cout << "Deleting Node "
0065                 << j <<": " << *i<< " ..." << endl;
0066    
0067            if (Node<classNode*>* p
0068                 = dynamic_cast<Node<classNode*>*>(*i))
0069            {
0070                cout << "Deleting "
0071                     << p->getData() << " ..." << endl;
0072                delete p->getData();
0073            }
0074            delete *i;
0075        }
0076    }
0077    

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值