Бинарные деревья - Трассировка с помощью кода

голоса
0

Учитывая бинарное дерево показаны ниже, определяет порядок , в котором узлы двоичного дерева , показанном ниже, при условии , посещаемые функция А (корень) вызываются. Предположим , что узлы дерева и указатели определяются как показано на рисунке. Предположим , что корень является указателем на узел , содержащий 60. Мой ответ на этот вопрос дается ниже. Является ли это правильно? Что я сделал не так?

                                   60
                                 /    \
                                30     90
                               /  \   / 
                              5   38  77
                               \  /  / \
                               8 32 62  88



struct treeNode{
  int data;
  struct treeNode *left, *right:
  {

struct treeNode *tree_ptr;

void A(struct treeNode *node_ptr){
    if (node_ptr != NULL){
    printf(“%d ,”,node_ptr->data);
    B(node_ptr->left);
    B(node_ptr->right);
   }   
}

void B(struct treeNode *node_ptr){
    if (node_ptr != NULL) {
    A(node_ptr->left);
    printf(“%d ,”,node_ptr->data);
    A(node_ptr->right);
   }
 }   

Ответ: В ничтожных А это говорит первые печатные node_ptr-> данные так 60 распечатан Тогда функция вызывает B (node_ptr-> левый) , то в B, A вызывается (node_ptr-> слева) , то при печати , что данные , которые 5 . И тогда A (node_ptr-> справа) вызывается вернуться к печатайте , что данные так 8 распечатаны. Теперь я не уверен , что делать дальше , но я получаю логически было бы целесообразно , чтобы напечатать 30 , но я не уверен , как PTR получает от 8 до 30. А потом , если вы будете продолжать в той же схеме 38 распечатана и 32 печатается. Для правого поддерева ... 90 77 62 88

Задан 14/12/2010 в 22:05
источник пользователем
На других языках...                            


4 ответов

голоса
1

Для начала, ваш код имеет кучу ошибок в нем. Я предполагаю, что это должно быть больше, как это:

struct treeNode{
  int data;
  struct treeNode *left, *right;
}

treeNode *tree_ptr;

void A(treeNode *node_ptr){
    if (node_ptr != NULL){  /// this could be just if(node_ptr)
        printf(“%d ,”,node_ptr->data);
        B(node_ptr->left);
        B(node_ptr->right);
    }   
}

void B(treeNode *node_ptr){
    if (node_ptr != NULL) {
        A(node_ptr->left);
        printf(“%d ,”,node_ptr->data);
        A(node_ptr->right);
    }
}   

Вы также смешивание двух различных алгоритмов обхода. A()это предварительный заказ, B()в заказе. A()и B()должно быть называющими себя, а не друг с другом. (Еще одна причина , чтобы использовать реальные переменные / имена функций вместо A, Bи тому подобное.)

Ответил 14/12/2010 в 22:11
источник пользователем

голоса
1

Просто напишите полный стек выполнения в течение долгого времени. Как это:

A(60)
  printf
  B(30)
    A(5)
      ...
    printf
    A(38)
      ...
  B(90)
    ...

(Остальная часть дерева остается в качестве упражнения для читателя.)

Тогда просто идти сверху вниз, записывая результаты заявлений PRINTF.

Ответил 14/12/2010 в 22:14
источник пользователем

голоса
1

Aявляется предварительным заказом обходом, в то время как Bэто в обходе по заказу.

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

ОБНОВИТЬ

Причина 30 печатается после 5 и 8, что вы не выполняете обход чисто предварительный заказ. Вы прыжки между предзаказом и обходом упорядоченным.

Самый простой способ выяснить порядок является на самом деле записать шаги код через которые проходят, как вы проследите через него (я часто использую ручку / карандаш и бумагу, чтобы сохранить информацию вместе). Например, вы могли бы сделать выписать колл-стек, как это:

A(60)
  printf(60)
  call B(60.left)
    B(30)
      call A(30.left)
        A(5)
          printf(5)
          call B(5.left)
            B(null)
          call B(5.right)
            B(8)
              call A(8.left)
                A(null)
              printf(8)
              call A(8.right)
                A(null)
      printf(30)
      call A(30.right)
        A(38)
        ...

Вы можете легко увидеть порядок, в котором узлы печатаются, и что более важно, почему вы «прыгать» из печати 8 к печати 30 (один рекурсивный вызов закончился, и вы падаете назад на один уровень).

Ответил 14/12/2010 в 22:15
источник пользователем

голоса
1

след, как указано выше, не может быть правильным или для предварительного заказа или в заказ Предварительно - 60, 30, 5, 8 35 32 и т.д. В - 5, 8, 30, 32, 35 и т.д.

Ответил 28/03/2011 в 09:59
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more