创建泛型链表,将下一个指针放在结构的开头

Making Generic Linked list placing next pointer at beginning of structure

本文关键字:结构 开头 指针 下一个 泛型 链表 创建      更新时间:2023-10-16

我正在读其中一本书,却被一个特定的问题卡住了。

链表结构体的定义:::

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

马里奥