Как отобразить следующий элемент в последовательности для сбалансированного бинарного дерева? (в целях)

Итак, я создаю АТД упорядоченного набора, используя для назначения древовидную реализацию. И одним из требований является реализация итератора для множества. И у меня возникли проблемы с тем, как я должен возвращать следующий элемент в последовательности, когда я использую рекурсию для обхода дерева. Я думал об использовании цикла while, чтобы добраться до самого левого листа (узла), но я не уверен, как вернуться к родительскому узлу. Вот реализация дерева, которую я использую, и ее заголовок. Вот объявление набора и его header. Любая помощь приветствуется.

/*
 * Returns the next element in the sequence represented by the given
 * set iterator.
 */
void *set_next(set_iter_t *iter)
{
  if(iter->node == NULL)
    printf("tree iterator exhausted");
  else
  {
    void *elem;
    while(iter->node->left != NULL)
      iter->node = iter->node->left;
    return elem;
  }
}

Редактировать: я попытался сохранить обход в массиве, но похоже, что функция неправильно выполняет итерацию по массиву:

static int i = 0;
void *set_next(set_iter_t *iter)
{

  if(iter->node == NULL)
    printf("tree iterator exhausted");
  else
  {
    int size = iter->node->numitems;
    int arr[size];
    int *p;
    p = arr;
    void *elem;
    store_inorder(iter->node, p, i);
    elem = (p+i);
    return elem;
    ++i;
  }
}

Вот функция, которую я использую для хранения обхода в массиве:

void store_inorder(tree_t *tree, int inorder[], int index_ptr)
{
    if (tree == NULL)
        return;
    void *p = malloc(sizeof(intptr_t));;
    p = tree->data;
    /*first recur on left child */
    store_inorder(tree->left, inorder, index_ptr);
    inorder[index_ptr] = (intptr_t)tree->data;
    (index_ptr)++;  // increase index for next entry

    /*now recur on right child */
    store_inorder(tree->right, inorder, index_ptr);
}

person Doe J    schedule 25.03.2018    source источник
comment
Вызовите указатель функции с узлом в качестве параметра.   -  person Martin James    schedule 25.03.2018
comment
Я гуглил указатель функции и понимаю синтаксис, но я не совсем уверен, что он на самом деле делает (помимо очевидного, указывая на функцию), зачем использовать его вместо вызова функции?   -  person Doe J    schedule 25.03.2018


Ответы (2)


Вы можете запомнить местоположение своего итератора, сохранив обратный путь от текущего местоположения к корню.

Вспомните Гензеля и Гретель.

person N. Paul    schedule 25.03.2018
comment
Конечно! У меня даже есть функция, которая хранит мой обход в массиве, я попробую! Спасибо. - person Doe J; 25.03.2018

Можете ли вы просто изменить узел так, чтобы он включал родителя? Если итерация является частью определения проблемы, то наличие родительского указателя значительно упрощает задачу. И обратите внимание, что вам нужно идти вверх, пока дочерний элемент ссылается через правого дочернего элемента своего родителя, а не только через ближайшего родителя.

person SoronelHaetir    schedule 25.03.2018