【问题标题】:How to work with this singly linked list?如何使用这个单链表?
【发布时间】:2020-09-05 06:41:33
【问题描述】:

我有一个奇怪的链表(代码不是我的):

struct _P_NEXT
{ P_NEXT* p_el; };

如您所见,没有数据字段。但是,列表必须包含复杂的结构。 为了便于说明,我给出了一种在列表末尾添加项目的方法:

void in_tail(P_NEXT* head_list, P_NEXT* el_list) {

    el_list->p_el = NULL;

    P_NEXT* el;
    el = head_list->p_el;

    if (el) {
        while (el->p_el)
            el = el->p_el;

        (el->p_el) = el_list;
    }
    else {
        head_list->p_el = el_list;
    }
}

【问题讨论】:

  • 您的问题到底是什么?你需要什么?
  • 结构体命名为_P_NEXT,而结构体中的指针类型为P_NEXT*。有什么联系?可能不仅仅是typedef
  • C 还是 C++?提供的代码是 C。为什么用 C++ 标记问题?
  • 也许你可以以某种方式使用类型转换?指针?

标签: c++ c struct linked-list


【解决方案1】:

这种结构通常用作intrusive list

这在没有类型多态性的 C 语言中通常很有用,但您希望拥有通用的维护和实用功能。

使用示例:

struct node {
    struct _P_NEXT list; // must be the first member of the structure
    int data; 
    // and so on ....
};


并且您仍然可以将in_tail 与上面定义的struct node 一起使用,因为结构在内存中的布局方式,node 的地址将与其第一个成员的地址相同(@987654327 @)。

示例:

struct node head;
head.list.p_el = NULL;
// init head data
for(int i=0; i < 10; ++i) {
    struct node node = malloc(sizeof(struct node));
    // set node data
    in_tail((struct _P_NEXT*)&head, (struct _P_NEXT*)node);
}

你可以用同样的方式编写一个清理列表函数:

void cleanup_list(P_NEXT* list) {
    while(list !=NULL) {
        P_NEXT* current = list;
        list = current -> p_el;
        free(current);
    }
}

并调用相同的:

cleanup_list((P_NEXT*)head.list.p_el);

【讨论】:

  • 请注意,根据实现的不同,实际上可能不需要将struct _P_NEXT 作为第一个成员。例如,linux 链表实现提供了一些宏,这使得该成员可以在结构中的任何位置(甚至是多个不同的)。但是将其作为第一个成员当然总是安全的。
  • 感谢@FelixG 非常好的评论和点,了解更多关于这个0xax.gitbooks.io/linux-insides/content/DataStructures/…,这样的“魔法”是由以下宏“#define offsetof(TYPE, MEMBER) ((size_t ) &((TYPE *)0)->会员)"
  • 这太棒了!整天坐着没有结果。在 SOF 上询问并立即回答))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 2019-12-18
  • 2021-07-11
  • 2021-06-24
相关资源
最近更新 更多