异质链表的实现

异质链表 异质链表可以包含派生于同一个基类的不同元素。首先我们看看主程序和运行结果: void main() { Person ps1(0, "Tom", "19850615", 'M'); Person ps2(0, "Jam", "19850637", 'M'); Student st1(0, "Mike", "92876639", 'M', 100); Sta 阅读详情

一、目标

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


 

二、思路

【思路一】

在结点中用共用体保存数据,用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    

【数据结构】C语言实现线索二叉树 【数据结构】第五章——树与二叉树——线索二叉树 详细介绍C语言实现线索二叉树以及线索二叉树的遍历 阅读详情

相关推荐

二叉树三种遍历(动态图+代码深入理解)

文章目录一、图示理解(图片是一位前辈所留,在此感谢)1、先序遍历2、中序遍历3、后序遍历4、层序遍历二、深入理解三种遍历让我们来理解一下绕着外围跑一整圈的真正含义是:遍历所有结点时,都先往左孩子走,再往右孩子走。下面做一个实例吧三、代码实现加以理解以下是C语言全部代码实现下面是同样的例子用c++实现,大家可以参考一下 一、图示理解(图片是一位前辈所留,在此感谢) 1、先序遍历 先序遍历可以想象成,...

流楚丶格念的博客 3万+

C++刷题知识点总结2

1.什么是异质链表? 异质链表是指可以链表指针所指向的数据类型并不一致,比如一个链表中可以既存储整形数据,又可以存储浮点性的数据。在面向对象的语言中甚至就是可以指向不同的对象。而普通链表其数据类型必须一致。 先思考一下, 如果将这些不同类型的对象用链表进行直接链接, 显然不太好操作(不能用for循环来搞), 换个思路吧, 我们可以抽象出这些对象的共同点, 将这些共同点构造成结点, 然后把这些结点串...

qq_36692284的博客 1134

C++异质链表的实现与应用

本文还有配套的精品资源,点击获取 简介:C++中的异质链表是一种能够存储不同类型数据的链表结构,其设计利用了面向对象编程的核心特性,如继承、多态和动态类型转换。本文将详细介绍如何在C++中实现异质链表,包括基类的定义、派生类的创建、多态的应用、节点的插入与遍历、以及内存管理的策略。通过理论与实践相结合的方式,本文旨在帮助读者深入理解并应用这一高级数据结构。 1. ...

weixin_42113456的博客 1540

[C++] 多态性实战:异质链表

异质链表,是一种每个节点可以存储不同类型对象的链表。C++实现异质链表,的关键技术是模版元编程和多态性,不多说,直接看代码。 代码主要分为两部分:AnyElement.h 和 AnyList.h AnyElement.h包含AnyElment、ElementBase、Element 三个类;ElementBase和Element嵌套在An...

weixin_33795833的博客 513

实现异质链表的面向对象方法

异质链表(Heterogeneous Linked List)是指链表中的节点可以存储不同类型的数据。与传统同质链表(每个节点类型固定)不同,它更类似于数组,可以在数组中存储不同类型的数据,但是保留了链表的动态插入和删除优势。

weixin_30838971的博客 1013

C语言实现异质链表,可存储int、float、字符串等

C语言实现异质链表,可存储int、float、字符串等 链表支持插入、删除、逆置、合并、输出、销毁等

剖析十大经典二叉树题目:C 语言代码实现与深度解读

本文以“剖析十大经典二叉树题目:C 语言代码实现与深度解读”为题,详细解析了十大经典二叉树题目并给出 C 语言代码实现及代码解析。涵盖二叉树的遍历(前序、中序、后序遍历)、二叉搜索树相关操作(验证、插入、删除)、二叉树高度与平衡判断以及二叉树的路径问题(所有路径、路径总和)。通过对每个题目的描述、代码实现和代码解析,帮助读者深入理解二叉树的相关知识和算法,提升在数据结构和算法方面的编程能力与问题解决能力。

A Charmer 的博客 2213

C++实现异质链表

按照OOP编程思想,遵循《C++ Coding Standard.pdf》,编写完整的关于异质链表,并检验效果。

C语言实现二叉树(纯新手向)

目录 一、二叉树的基本概念 二、二叉树的初始化 三、释放二叉树 四、前中后序遍历二叉树 五、主函数和效果截图 六、拓展时间 这是我这段时间学习c语言二叉树的成果,希望对大家有所帮助,共同进步! 一、二叉树的基本概念 二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。定义结构体可以这样设计 代码

weixin_44606789的博客 2万+

一个异质链表类的实现

/* 题目: 大学中的人员分三类 :学生,教师和职员,他们的基本信息如下: 学生:姓名,年龄,学号,年级,成绩 教师:姓名,年龄,身份证号,职称,工资 职员:姓名,年龄,身份证号,工资 现在需要管理各类人员的信息,请用面向对象的方法设计一个异质链表,用来存放他们的信息。 异质链表实现:有三个类 student,teacher,staff,再定义一个 链表类,此类用来存放这几个不同类的对象,并将链表类 list 声明为所有这些 类的友元,使它们可以访问它们的私有成员。*/

c++写的异质链表,使用多态实现

自己写的c++异质链表,使用继承的多态性实现

二叉树求最大宽度(C语言实现)

最浅显易懂的求树最大深度的方法

weixin_61821927的博客 3478

异质链表的C语言实现

用C语言实现的一个异质链表。模拟实现不同数据类型的存储。

数据结构之平衡二叉树C语言版

作者:Cukor Zhong 什么是平衡二叉树 平衡二叉树是具有平衡属性的有序二叉树,所谓的平衡即当前树的左右子树高度差的绝对值不超过1。因为平衡二叉树是由苏联数学家Adelson-Velskii和Landis提出,所以又称为AVL树。 平衡二叉树的基本特点 是特殊的有序二叉树 左右子树高度差的绝对值不超过1 左右子树仍然是平衡二叉树

Cukor丘克的博客 5087

告别报错!Win10下Autodock Vina 1.2.3保姆级安装与避坑指南

本文提供了Win10系统下Autodock Vina 1.2.3的完整安装与实战指南,涵盖环境配置、分子文件预处理、对接参数优化及结果分析等关键步骤。通过详细的避坑技巧和优化方案,帮助用户高效完成分子对接任务,特别适合生物信息学研究人员和药物发现领域的初学者。

weixin_29969209的博客 404

ROS2_IGH方案配置(二)——Ubuntu22.04 实时内核性能验证与调优

本文详细介绍了在Ubuntu22.04系统上配置ROS2_IGH方案时,如何验证和调优PREEMPT_RT实时内核性能。通过使用cyclictest工具进行基准测试和压力测试,分析中断与硬件延迟,并优化内核参数,确保系统满足工业控制领域对硬实时性的苛刻要求。文章还提供了针对ROS2的特殊优化建议和性能监控方案,帮助开发者实现毫秒级延迟的稳定控制。

weixin_30791095的博客 224

数据结构_求二叉树的高度以及层次遍历二叉树算法_C语言源代码

int Height(BTNode *T)//求二叉树高度 {     int L,R;     if(NULL == T)          return 0;     else     {           L=Height(T->lchild);         R=Height(T->rchild);         return  L>R ? L+1 :R+1;  

u013227200的专栏 3487

全志 T527_Android13 编译 [ 避坑必看 ]

Swap 概念: Linux中Swap(即:交换分区),类似于Windows的虚拟内存,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。它的功能就是在内存不够的情况下,操作系统先把内存中暂时不用的数据,存到硬盘的交换空间,腾出内存来让别的程序运行。当输入编译命令make -j16 的时候,会有如下提示,这是官方建议通过减少编译线程来解决编译时消耗内存过大的问题。Android 13 系统的编译流程,编译一共分为两部分:内核编译与 Android 编译。

公众号:嵌入式分享 2111

c语言二叉树的理解与实现

从树到,堆,大小堆实现,堆排序,二叉树的遍历方法及所有函数的解析

morixi的博客 1143

别再花屏了!手把手教你用STM32CubeIDE搞定LVGL 8.3移植(附完整源码)

本文详细介绍了如何在STM32CubeIDE环境下成功移植LVGL 8.3,解决常见的花屏问题。从环境配置、显示驱动优化到编译警告处理,提供完整的实战方案和源码示例,帮助开发者快速实现流畅的嵌入式GUI界面。特别针对STM32平台的DMA2D加速和内存管理进行了深度优化。

weixin_33739646的博客 243

BurpSuite工具HaE插件好用正则收集

数据集合面板里面直接查询捕获到的相关数据内容,省去一个个翻找数据包内容的烦恼。插件捕获到匹配正则表达式的数据包后,可以在。可以对正则条目进行添加、编辑、删除。规则信息管理,我们点击。

墨痕诉清风的博客 651

C 语言 二叉树的实现详解!!!(每种方法都详细解释,哪里不会看哪里)

(建议先看后续遍历,就是先遍历全部节点,在进行操作)进行从遍历的最后一个节点开始,进行free,如果用前序遍历free的话,那你第一个根节点都free了你就找不到你的子树了,而中序遍历的话,就比如你刚把D删除了,中序遍历的话就会把 B先删除,那就找不到E节点,E节点就没被删除。那也就明了了 中序遍历就是 你先把左边走到 底 然后 先打印左边,在打印根的,在打印右边的。就像这里的打印的一样,你先把A打印出来了,然后 在走你的左边,打印出B后继续走B的左边,打印出D后,返回到B节点,B又走他的右边 打印E。

a1275174052的博客 1561

47_AI智能体核心业务之全局主控Agent:智能对话系统的统一指挥中心

本文介绍了全局主控Agent的架构设计与实现,该组件作为智能对话系统的统一指挥中心,提供标准化的多模式处理接口。系统支持普通对话、工具命令执行和流式响应三种处理模式,通过智能工作流路由协调多个处理引擎。统一的消息封装和异步架构设计确保了系统的高性能和可扩展性,已成功处理300万次用户请求,平均响应时间1.2秒。

在科技的浪潮中,我们寻找着创新的火种,在代码的海洋里,我们编织着智慧的网。腾飞开源,就是这样一个由技术精英汇聚而成的博客平台,我们致力于分享在Java、Python、IoT和人工智能等领域的最新研究成果和实战经验。 在腾飞开源的博客上,你会看到紧跟技术前 344

C实现:求二叉树的高度

理论思路 (图来自浙大数据结构课程) 很明显,求树的高度,是左右子树中最高的再加一。 那么怎么求左子树的高度呢?就是其左右子树中最高的加一。 那么怎么求右子树的高度呢?就是其左右子树中最高的加一。 这样就形成了 递归,我们利用后序遍历的程序,稍加修改便可成为求二叉树高度的程序。 求二叉树高度: int PostOrderGetHeight(BinTree BT){ int HL,HR,MaxH; if(BT){ HL=PostOrderGetHeight(BT->Left); HR=Po

weixin_44915226的博客 1万+

SAP SLT 在 carve-out 场景中的关键作用:从理论到实操全景展现

深入剖析 SAP Landscape Transformation(SLT Replication Server)在 carve‑out 场景中的价值,需要从 carve‑out 本身的背景逻辑说起。carve‑out 指的是企业因并购、拆分、剥离商业单元等因素,而将 SAP 系统中某部分业务(例如组织单元、公司代码、模块数据等) separated 出来,导入到独立的系统中。这一过程极具挑战性,既要确保业务连续性,又要实现数据精准迁移和系统隔离 (

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 7554

silero-vad 训练自己的数据

silero-vad 训练自己的数据

jacke121的专栏 816
下一篇: 生产者/消费者问题在windows2000下的实现
elmar
博客等级 码龄25年 1粉丝 4原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值