Дерево, с неверным обходом - PascalABC.NET

Узнай цену своей работы

Формулировка задачи:

В общем, есть программа, в которую я добавил доп. функцию "обхода в ширину" и она работает неверно. Эта процедура выдает элементы не по уровням, а просто в порядке, в каком изначально дано дерево. Как исправить? Всем добра (код прилагаю ниже)

Решение задачи: «Дерево, с неверным обходом»

textual
Листинг программы
// uses crt;
const
  n = 10;
 
type
  PTree = ^TTree;
  TTree = record
    num: integer;
    LEFT, RIGHT: PTree;
  end;
  tarr = array[0.. n - 1] of PTree;
 
var
  a: array[1..n] of integer;
  i, z, v, max, x: integer;
  predkor, Hkor, kor: Ptree;
 
 
 
 
////вывод дерева на экран////
procedure print(TREE: Ptree; n: integer);
var
  q: integer;
begin
  if TREE <> nil then             //пока элемент не равен nil
  begin//выводим кол-во пробелов, равное уровню
    for q := 1 to n do
      write('*');                //Выводим ключ
    writeln(TREE^.num);            //повторяем для левого и правого
    print(TREE^.LEFT, n + 1);
    print(TREE^.RIGHT, n + 1);
  end;
end;
 
 
 
 
 
////вставка////
procedure insert(var TREE: Ptree; x: integer);
var
  CUR, TNEW: PTree;
begin
  ////////Текущему - начальный/////////
  CUR := TREE;
  //////// Если список пустой///////
  if CUR = nil then
  begin
    new(TNEW);
    TNEW^.num := x;
    TNEW^.LEFT := nil;
    TNEW^.RIGHT := nil;
                         //Присвоить начальному - текущий
    Hkor := TNEW;
  end
                          //Если списой не пустой
  else
  begin
                      //Если текущий элемент больше введенного
    new(TNEW);
    TNEW^.num := x;
    TNEW^.RIGHT := nil;
    TNEW^.LEFT := nil;
    if CUR^.num > x
      then
      /////////Если слева нет элемента///////////
      if CUR^.LEFT = nil
       then
       ////////поставить элемент слева//////
      begin
        TREE^.LEFT := TNEW;
      end
         ////////Если есть элемент, то перескочить на него//////
      else begin CUR := CUR^.LEFT; insert(cur, x); end
    else
    ///////////то же с правым////////////
    if CUR^.RIGHT = nil
       then
    begin
      TREE^.RIGHT := TNEW;
    end
    else begin CUR := CUR^.RIGHT; insert(cur, x); end;
  end;
end;
 
 
 
////Очистка дерева////
procedure clear(var tree: ptree) ;
var
  cur: ptree;
begin
  cur := tree;
  if cur <> nil then
  begin
    clear(cur^.LEFT);
    clear(cur^.RIGHT);
    dispose(cur);
  end;
  tree := nil;
  
  
end;
 
////Обход дерева по уровням////
procedure PrintByLevel(level: integer;
          var items: tarr; count: integer);
var
  i, new_count: integer;
begin
  if count <> 0 then begin
    
    writeln('level = ', level);
    new_count := 0;
    for i := 0 to pred(count) do 
    begin
      write(items[i]^.num:4);
      if items[i]^.left <> nil then begin
        inc(new_count); items[count + new_count - 1] := items[i]^.left;
      end;
      if items[i]^.right <> nil then begin
        inc(new_count); items[count + new_count - 1] := items[i]^.right;
      end;
    end;
    writeln;
    for i := 0 to Pred(new_count) do
      items[i] := items[count + i];
    PrintByLevel(level + 1, items, new_count);
    
  end;
end;
 
 
 
 
/////меню////
 
procedure menu(v: integer);
var
  arr: tarr;
begin
  case  (v) of
    1: begin writeln('Введите ключ');read(z); insert(Hkor, z); end;
    2: begin if Hkor <> nil then print(Hkor, 0) else writeln('Дерево пусто'); end;
    3: begin clear(Hkor);  end;
    4:
      begin
        writeln(''); 
        arr[0] := HKor;
        PrintByLevel(0, arr, 1);
      end;
    0: v := 0;
  end;
  Writeln;
  writeln(' <<<<<<<<<<<<<<<<< Меню:>>>>>>>>>>>>>>>>>>>');
  writeln(' -----Добавление элемента в дерево-------- : 1');
  writeln(' --------------Печать дерева-------------- : 2');
  writeln(' ----- -------Очистка дерева ------------- : 3');
  writeln(' ------Обход дерева в порядке уровней----- : 4');
  writeln(' ------------------Выход ----------------- : 0');
  Writeln;
end;
 
 
 
 
 
 
 
////Начало программы////
 
begin
  a[1] := 7;
  a[2] := 5;
  a[3] := 9;
  a[4] := 3;
  a[5] := 1;
  a[6] := 10;
  a[7] := 6;
  a[8] := 8;
  a[9] := 4;
  a[10] := 2;
  Hkor := nil;
  for i := 1 to n do
  begin
    insert(Hkor, a[i]);
  end;
  v := 1;  writeln(' <<<<<<<<<<<<<<<<< Меню:>>>>>>>>>>>>>>>>>>>');
  writeln(' -----Добавление элемента в дерево-------- : 1');
  writeln(' --------------Печать дерева-------------- : 2');
  writeln(' ----- -------Очистка дерева ------------- : 3');
  writeln(' ------Обход дерева в порядке уровней----- : 4');
  writeln(' ------------------Выход ----------------- : 0');
  Writeln;
  while v <> 0 do
  begin
    readln(v);
    menu(v);
    Writeln;
  end;
end.

Объяснение кода листинга программы

  1. Начнем с объявления переменных и типов данных. У нас есть следующие переменные:
    • n (константа, обозначающая количество элементов в дереве)
    • PTree (тип данных, представляющий узел дерева)
    • TTree (тип данных, представляющий дерево)
    • tarr (массив, используемый для обхода дерева по уровням)
    • a (массив, содержащий ключи для добавления в дерево)
    • i, z, v, max, x (переменные, используемые в процедуре вставки и обхода дерева)
    • predkor, Hkor, kor (переменные, используемые в обходе дерева)
  2. Далее идут процедуры:
    • print (вывод дерева на экран)
    • insert (вставка элемента в дерево)
    • clear (очистка дерева)
    • PrintByLevel (обход дерева по уровням)
    • menu (основная программа, обрабатывающая пользовательский ввод)
  3. В основной программе создается дерево, заполняется массив a, инициализируется переменная Hkor как корневой узел дерева. Затем выполняется цикл, позволяющий пользователю взаимодействовать с программой через меню.
  4. В меню пользователю предлагаются следующие опции:
    • 1: Ввести ключ и добавить его в дерево
    • 2: Печать дерева
    • 3: Очистка дерева
    • 4: Обход дерева по уровням
    • 0: Выход из программы
  5. Процедура insert отвечает за вставку элемента в дерево. Она рекурсивно обходит дерево, ища место для вставки нового элемента. Если дерево пустое, новый элемент становится корнем. Если элемент больше текущего, он вставляется в правую поддерево. Если элемент меньше текущего, он вставляется в левое поддерево. Если элемент равен текущему, ничего не происходит.
  6. Процедура clear используется для очистки дерева. Она рекурсивно обходит дерево, очищая каждый узел, и затем освобождает память, выделенную под дерево.
  7. Процедура PrintByLevel используется для обхода дерева по уровням. Она принимает уровень, массив для хранения узлов и счетчик количества элементов. Она рекурсивно обходит дерево, печатая каждый узел и его ключ.
  8. Процедура menu обрабатывает пользовательский ввод и вызывает соответствующие процедуры в зависимости от выбранной опции.
  9. В начале программы создается дерево, заполняется массив a и выполняется цикл, позволяющий пользователю взаимодействовать с программой через меню.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 3 из 5
Похожие ответы