创建泛型链表,将下一个指针放在结构的开头
Making Generic Linked list placing next pointer at beginning of structure
我正在读其中一本书,却被一个特定的问题卡住了。
链表结构体的定义:::
typedef struct LinkedList{
LinkedList* next;
int data;
}
书上说:"将下一个指针放在结构体或类的开头,无论数据保存什么,都可以很容易地编写通用列表处理例程。"
我不明白把下一个指针放在上面会有什么帮助。
另外,要创建泛型列表,我们不需要数据类型为泛型或说void*吗?
您正在看的这本书Programming Interviews Exposed(据我所知)不是一本关于c++的书,而是一本旨在帮助您准备回答在典型的技术面试中可能被问到的各种问题的书。我不会把书中的任何内容作为最好的c++实践,除非它被贴上这样的标签(也许甚至不是这样)。
在链表节点结构中将下一个指针放在首位的建议来自C语言,在这些语言中,你不能依赖真正的、编译器支持的继承。实际上,其思想是通过将数据装载到链表节点结构上来实现类似继承的东西。考虑:
typedef struct LinkedList {
LinkedListNode* next;
int type;
}
typedef struct Person {
LinkedList listNode;
char name[64];
int age;
}
typedef struct Address {
LinkedList listNode;
char streetAddress[128];
char city[32];
char state[2];
char zip[10];
}
typedef struct Employee {
Person person;
int department;
int salary;
}
这里的LinkedList是一个基本类型——它本身不太好,但作为具有更多数据的节点的起点很有用。为了在节点上执行链表操作,您不必了解其他类型……您可以将任何节点指针强制转换为LinkedList*,并访问您需要的信息。你可以有Person列表和Address列表,两者都可以用同一套例程来操作。同样,您可以将Employee*转换为Person*,并在Employee上使用您为Person编写的任何操作。如果你给LinkedList的type
字段分配适当的常量,你甚至可以混合PersonNode并使用type
字段来确定每个节点的类型。
这在20多年前是一种很有用的编程方式。当然,它仍然可以工作,但是如果可以的话,大多数人会选择让编译器为他们管理继承,并且所有现代面向对象语言都提供了这个选项。
教训:如果您在旧代码中遇到这种技术,请理解它,但如果可以,请为新代码选择不同的实现。
如果你把下一个指针放在开头,而你只有一个void*,但你知道它是一个链表节点,你总能找到下一个指针。这与下一个指针放置在'data'之后形成对比,假设'data'可以有不同的大小,你需要了解更多关于对象的信息才能找到下一个指针
我个人认为没有任何理由,我同意,参数应该被模板化:
template <class T> class ListElement
{
T data;
ListElement* next;
...
}
可能会有一些关于内存对齐的速度问题,但我怀疑这一点!
hth
马里奥相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 设计将引用元素移动到开头的数据结构.C++
- C++中的数据结构,插入链表中节点的开头
- 什么是结构开头的函数列表指针,称为 c++
- 从偏移量开始复制到结构的开头
- 创建泛型链表,将下一个指针放在结构的开头