Однонаправленный линейный список. Формирование на его основе бинарного дерева - C (СИ)

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

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

Нужно создать однонаправленный линейный список(элементы списка вводятся с клавиатуры и имеют свои ключи(целое без знака с произвольным значением) и сформировать на его основе бинарное дерево. Программа должна реализовывать следующие действия: включить новый элемент после i-го по номеру элемента, включить новый элемент вместо i-го по номеру элемента, поменять местами два элемента с заданными ключами, удалить все листья на заданном уровне дерева, определить количество листьев на каждом уровне дерева. Дерево выводить в виде таблицы с указанием вида обхода. P.S. Не обязательно, что бы все было как в условие P.P.S. Заранее огромная благодарность за помощь.

Решение задачи: «Однонаправленный линейный список. Формирование на его основе бинарного дерева»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <malloc.h>
  5.  
  6. typedef struct node {
  7.     struct node* next; //right
  8.     struct node* prev; //left
  9.     unsigned val;
  10. } node_t;
  11.  
  12. int list_input(const char* str, node_t** lst);
  13.  
  14. node_t* bstree_make(node_t** lst);
  15. void bstree_print(FILE* _out, const node_t* tr);
  16. void bstree_clear(node_t* tr);
  17. void bstree_sheets(FILE* _out, const node_t* tr);
  18. void bstree_remove_sheets(node_t** tr, unsigned level);
  19. static void _bst_remove_sheets(node_t** tr, unsigned i, unsigned level);
  20. static unsigned _bst_height(const node_t* tr);
  21. static void _bst_count(const node_t* tr, unsigned* arr, unsigned i);
  22.  
  23.  
  24. int main(void){
  25.     char    buf[256];
  26.     node_t* lst = NULL;
  27.  
  28.     //для примера
  29.     strcpy(buf, "5 4 2 0 1 3 7 6 9 8");
  30. /*  printf("Enter: ");
  31.     fgets(buf, sizeof(buf), stdin);*/
  32.     list_input(buf, &lst);
  33.  
  34.     node_t* tr = bstree_make(&lst);
  35.     bstree_print(stdout, tr);
  36.     putchar('\n');
  37.     bstree_sheets(stdout, tr);
  38.     putchar('\n');
  39.  
  40.     //удалить листья на 4-ом уровне(уровень начинается с нуля)
  41.     bstree_remove_sheets(&tr, 3);
  42.     bstree_print(stdout, tr);
  43.     putchar('\n');
  44.     bstree_sheets(stdout, tr);
  45.  
  46.     bstree_clear(tr);
  47.     getchar();
  48.     return 0;
  49. }
  50.  
  51. //ввод списка со строки
  52. int list_input(const char* str, node_t** lst){
  53.     char*    off;
  54.     node_t*  tail, *p;
  55.     unsigned val;
  56.  
  57.     tail = *lst = NULL;
  58.     while(*str){
  59.         val = strtoul(str, &off, 10);
  60.         if(str == off)
  61.             break;
  62.         str = off;
  63.  
  64.         if((p = (node_t*)malloc(sizeof(node_t))) == NULL)
  65.             break;
  66.        
  67.         p->next = p->prev = NULL;
  68.         p->val  = val;
  69.  
  70.         if(tail == NULL)
  71.             *lst = tail = p;
  72.         else {
  73.             p->prev = tail;
  74.             tail    = tail->next = p;
  75.         }
  76.     }
  77.     return 1;
  78. }
  79.  
  80. //превращение двусвязного списка в двоичное дерево поиска, дубликаты удаляются
  81. node_t* bstree_make(node_t** lst){
  82.     node_t* i, *p;
  83.     node_t* root = NULL, **ref = NULL;
  84.  
  85.     while(*lst != NULL){
  86.         p    = *lst;
  87.         *lst = (*lst)->next;
  88.         if(*lst != NULL)
  89.             (*lst)->prev = NULL;
  90.  
  91.         p->next = p->prev = NULL;
  92.  
  93.         if(root == NULL)
  94.             root = p;
  95.         else {
  96.             ref = &root;
  97.             i   = root;
  98.             while(i != NULL){
  99.                 if(p->val < i->val){
  100.                     ref = &i->prev;
  101.                     i   = i->prev;
  102.                 } else if(p->val > i->val){
  103.                     ref = &i->next;
  104.                     i   = i->next;
  105.                 } else
  106.                     break;
  107.             }
  108.  
  109.             if(i != NULL)
  110.                 free(p);
  111.             else
  112.                 *ref = p;
  113.         }
  114.     }
  115.     *lst = NULL;
  116.     return root;
  117. }
  118.  
  119. //удаление всех листьев дерева на определённом уровне
  120. void bstree_remove_sheets(node_t** tr, unsigned level){
  121.     _bst_remove_sheets(tr, 0, level);
  122. }
  123.  
  124. static void _bst_remove_sheets(node_t** tr, unsigned i, unsigned level){
  125.     int m;
  126.     if(*tr != NULL){
  127.         m = 0;
  128.         if((*tr)->prev != NULL){
  129.             _bst_remove_sheets(&(*tr)->prev, i + 1, level);
  130.             ++m;
  131.         }
  132.         if((*tr)->next != NULL){
  133.             _bst_remove_sheets(&(*tr)->next, i + 1, level);
  134.             ++m;
  135.         }
  136.  
  137.         if((m == 0) && (i == level)){ //есть это лист, то удалим его
  138.             free(*tr);
  139.             *tr = NULL;
  140.         }
  141.     }
  142. }
  143.  
  144. //печать: кол-во листьев на каждом уровне дерева
  145. void bstree_sheets(FILE* _out, const node_t* tr){
  146.     unsigned* arr;
  147.     unsigned i, n = _bst_height(tr);
  148.     if(n == 0)
  149.         return;
  150.  
  151.     arr = (unsigned*)calloc(n, sizeof(unsigned));
  152.     if(arr == NULL)
  153.         return;
  154.  
  155.     _bst_count(tr, arr, 0);
  156.     for(i = 0; i < n; ++i)
  157.         fprintf(_out, "level: %u\tcount sheets: %u\n", i, arr[i]);
  158.     free(arr);
  159. }
  160.  
  161. //подсчёт листьев
  162. static void _bst_count(const node_t* tr, unsigned* arr, unsigned i){
  163.     if(tr != NULL){
  164.         if((tr->prev == NULL) && (tr->next == NULL))
  165.             ++arr[i];
  166.  
  167.         if(tr->prev != NULL)
  168.             _bst_count(tr->prev, arr, i + 1);
  169.         if(tr->next != NULL)
  170.             _bst_count(tr->next, arr, i + 1);
  171.     }
  172. }
  173.  
  174. //высота дерева
  175. static unsigned _bst_height(const node_t* tr){
  176.     unsigned a, b;
  177.     if(tr != NULL){
  178.         a = (tr->prev != NULL) ? _bst_height(tr->prev) : 0;
  179.         b = (tr->next != NULL) ? _bst_height(tr->next) : 0;
  180.         return ((a > b) ? a : b) + 1;
  181.     }
  182.     return 0;
  183. }
  184.  
  185.  
  186. //обход в прямом порядке
  187. void bstree_print(FILE* _out, const node_t* tr){
  188.     if(tr != NULL){
  189.         fprintf(_out, "%u ", tr->val);
  190.         if(tr->prev != NULL)
  191.             bstree_print(_out, tr->prev);
  192.         if(tr->next != NULL)
  193.             bstree_print(_out, tr->next);
  194.     }
  195. }
  196.  
  197. //удаление всего дерева
  198. void bstree_clear(node_t* tr){
  199.     if(tr != NULL){
  200.         if(tr->prev != NULL)
  201.             bstree_clear(tr->prev);
  202.         if(tr->next != NULL)
  203.             bstree_clear(tr->next);
  204.         free(tr);
  205.     }
  206. }

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

В данном коде реализована задача формирования однонаправленного списка из строки, а затем создания бинарного дерева поиска из этого списка. Затем в коде реализованы функции для удаления листьев на определенном уровне, подсчета количества листьев на каждом уровне и обхода дерева в прямом порядке. Список представлен в виде динамического массива, где каждый элемент - это структура node_t, содержащая указатели на следующий и предыдущий элементы списка, а также значение. Для решения задачи использованы следующие функции:

  1. list_input - ввод списка из строки. Строка разделяется на отдельные числа, которые затем добавляются в список.
  2. bstree_make - создание бинарного дерева поиска из списка. В процессе создания дерева, элементы списка сравниваются между собой, и если текущий элемент меньше значения элемента, на который указывает ссылка, то ссылка обновляется, указывая на текущий элемент. Таким образом, в итоге получается бинарное дерево поиска.
  3. bstree_print - обход дерева в прямом порядке и вывод его элементов.
  4. bstree_clear - очистка дерева, включающая освобождение памяти, выделенной под элементы дерева.
  5. bstree_sheets - подсчет количества листьев на каждом уровне дерева.
  6. bstree_remove_sheets - удаление всех листьев на определенном уровне дерева. Также в коде используется статическая функция _bst_remove_sheets, которая рекурсивно удаляет листья на определенном уровне.

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


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

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

9   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы