【问题标题】:C list class like progeram [closed]C列表类,如程序[关闭]
【发布时间】:2016-03-02 23:08:31
【问题描述】:

我需要在 C 中模拟一类链表。 我的问题是保存列表长度、头部、最后一个节点和创建每个“对象”的平均值等信息。 意义

List *A = ctor()
addItem(A, 0)

并检查 A 的列表长度将返回 2。 但是如果我做另一个名为 B 的列表,并添加另外两个项目,它将显示 3。 我不允许在任何函数中使用循环(不包括析构函数 - 也没有递归和 goto) 老实说,我想不出一种方法来保存每个“对象”的信息(现在缺少另一个词) 有什么建议么? 一切都在 C 中 我不想使用简单的全局变量,因为我仍然需要为每个实例保存不同的信息(找到单词)

编辑:

结构包含:

int value
List *next
List *previous

并且不能包含更多的值

编辑 2

我可以在结构中添加更多字段

要求是: 不要使用循环、递归、goto

列出函数:

1) 构造 - 创建一个新列表

2) Destruct - 删除所有节点(可以在该函数中使用循环)

3) 添加节点

4) 删除一个节点 - 给定一个指向该节点的指针

5) 返回列表的长度

6) 返回指向第一个节点的指针

7) 返回指向最后一个节点的指针

8) 返回指向下一个节点的指针(给定指向当前节点的指针)

9) 返回指向前一个节点的指针(给定指向当前节点的指针)

10) 节点的返回值(给定一个指向该节点的指针)

11) 返回列表中值的平均值

就是这样,功能不是很基础的时候说明不是这样的

限制性

不知道有没有帮助

【问题讨论】:

  • 使用struct 来包含所需的数据。类只是structs,带有自动构造函数/析构函数和相关函数。
  • "检查 A 的列表长度将返回 2"。为什么?您添加了 1 项,长度为 2?无论如何,为什么不能在List 结构中添加一个计数器字段?并为您需要跟踪的任何其他内容添加更多字段。
  • 你有next。如果您真的想计算项目数,则只需遍历所有 next 指针。但这需要循环。我怀疑要么你误解了要求,要么你的分配问题没有很好地形成。
  • 现在你的两个编辑是矛盾的。无论如何,这仍然没有意义。拥有next/prev 链是没有意义的,除非代码会在某处遍历它们。而且你不能遍历没有循环、goto、递归等的可变长度链表。正如建议的那样,如果你粘贴 exact 赋值语句会更好。
  • @Martinn 如果要求措辞更狭窄,您所说的可能是正确的。就像“创建新列表节点时没有循环”。但是一揽子“无循环”要求是没有意义的。如何在中间找到一个节点?关键是要求不明确。如果我们从错误的需求开始,我们将永远无法找到正确的解决方案。要求 OP 在上下文中粘贴作业的确切措辞真的那么不合理吗?

标签: c list loops object


【解决方案1】:

免责声明:我假设您的函数只能与节点一起操作,这就是为什么我向调用者隐藏列表结构,导致 API 混乱。


好的,这将赢得最差 API 奖,但这里有一个可能的解决方案:

struct node;

struct list {
  int sum;
  size_t count;
  struct node * head, * end;

struct node {
  struct node * next, * previous;
  struct list * list;
  int value;
};

struct node * allocate_list(void) {
  struct node * sentinel = malloc(sizeof(*sentinel));
  struct list * list = malloc(sizeof(*list));
  sentinel->previous = sentinel->next = NULL;
  list->head = list->end = sentinel;
  list->sum = 0;
  list->count = 0;
  sentinel->list = list;
  return sentinel;
}

void free_list(struct node * n) {
  struct list * list = n->list;
  n = list->head;
  while (n != list->end) {
    n = n->next;
    free(n->previous);
  }
  free(n);
  free(list);
}

void add_item(struct node * n, int value) {
  struct node * new = malloc(sizeof(*new));
  new->previous = n->previous;
  n->previous = new;
  new->next = n;
  new->value = value;
  new->list = n->list;
  if (new->previous == NULL) {
    new->list->head = new;
  }
  ++(new->list->count);
  new->list->sum += value;
}

其余的函数应该是微不足道的,绝对不需要任何循环或递归。

关键思想是将指向整个列表共享的数据的指针存储到每个节点。因此,可以从任何节点访问和修改此共享数据。

【讨论】:

  • 我采用了不同的方法,但感谢您抽出宝贵时间!它确实帮助了我
  • @Yarden 如果您愿意,可以通过将其发布为答案来分享您的方法。 (这里可以回答你的项目问题)
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
相关资源
最近更新 更多