圆双向链表结束函数

时间:2015-12-07 14:04:02

标签: c linked-list c99 sentinel

在bool end()函数中程序会知道sentinel是开头还是结尾?我可以做一个检查,以确保它作为结束阅读哨兵吗?

#include "ring.h"
#include <stdlib.h>
#include <stdio.h>

struct node {
  int item;
  struct node *prev;
  struct node *next;
};
typedef struct node node;

struct ring {
  node *sentinel;
  node *current;
};

ring *new_ring() {
  ring *p;
  node *n;

  p = (ring *) malloc (sizeof(ring));
  n = malloc(sizeof(node));
  p->sentinel = n;
  n->next = n;
  n->prev = n;
  return p;
}

void start(ring *r) {
  r->current = r->sentinel;
}

bool end(ring *r) {
  return r->current == r->sentinel;
}

void forward(ring *r) {
  while (r->current != r->sentinel) {
     r->current = r->current->next;
  }
}

2 个答案:

答案 0 :(得分:1)

您的规格是:

  • 在第一个元素(ok)之前开始位置
  • 结束测试当前是否超过最后一个元素(ok)
  • 转发环上的一个元素(好的,除非在调用start()之后,你有current == sentinel,所以forward什么都不做!)

但是你应该回答这个问题:你需要实现对称函数吗?

如果答案为否,只需将开始更改为sentinel->next上的位置,即在环的第一个元素(如果存在)上更改,如果环为空则超过结束,并且完成。

如果答案是肯定的,那么你必须能够在第一次之前区分,在另一方面区分过去的结束

有两种简单的方法:

  • 使用布尔值来区分:

    struct ring {
      node *sentinel;
      node *current;
      bool end;
    };
    

    当您直接位于end(或任何其他读取函数)结束时的位置时,您只需将true设置为forward

  • 使用2个哨兵

    struct ring {
      node *before;
      node *after;
      node *current;
    };
    

    您应该使用before->next = after;after->prev = before

  • 对其进行初始化

答案 1 :(得分:1)

据我所知,您需要使用结束函数来确定这是否是环的最后一个节点,或者这是开头。

您可以修改您的结束功能,看起来像这样。

bool end(ring *r) {
    return r->current->next == r->sentinel;
}

如果环中只有一个元素,那么总是在启动函数之后,结束条件将为真。

如果有多个元素,那么一旦end返回true,r-&gt; current将是sentinel之前的最后一个元素。