Pers.narod.ru. Алгоритмы. Упражнения на бинарные деревья и списки |
Вершина дерева содержит динамический массив целых значений и два указателя на потомков. Значения в дереве не упорядочены. Размерность динамического массива в корневой вершине - N, на каждом следующем уровне - в 2 раза больше. Функция включает новое значение в свободное место в массиве ближайшей к корню вершины.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 2 typedef struct tree { char *value; unsigned int size; struct tree **child; } TREE; TREE *CreateNode(char *value, unsigned int size) { TREE *new_node = (TREE *) malloc(sizeof(TREE)); new_node->value = (char *) malloc(strlen(value) + 1); strcpy(new_node->value, value); new_node->size = size; new_node->child = (TREE **) malloc(sizeof(TREE) * new_node->size); for(unsigned int i = 0; i < new_node->size; i++) *(new_node->child + i) = NULL; return (new_node); } TREE *found_node; void ScanTree(TREE *node) { if(node == NULL) return; for(unsigned int i = 0; i < node->size; i++) if(node->child[i] == NULL) { if(found_node == NULL) { found_node = node; break; } else { if(node->size < found_node->size) { found_node = node; break; } } } for(i = 0; i < node->size; i++) ScanTree(node->child[i]); return; } TREE *InsertNode(TREE *root, char *value) { TREE *new_node = NULL; if(root == NULL) { root = CreateNode(value, N); return (root); } found_node = NULL; ScanTree(root); new_node = CreateNode(value, found_node->size * 2); for(unsigned int i = 0; i < found_node->size; i++) if(found_node->child[i] == NULL) { found_node->child[i] = new_node; break; } return (new_node); } void main(void) { TREE * root = NULL; root = InsertNode(root, "root"); InsertNode(root, "child_1"); InsertNode(root, "child_2"); InsertNode(root, "child_3"); InsertNode(root, "child_4"); InsertNode(root, "child_5"); InsertNode(root, "child_6"); //Добавьте здесь вывод того, что получается }
Вершина дерева содержит массив целых и два указателя на правое и левое поддерево. Значения в дереве не упорядочены. Естественная нумерация значений производится путем обхода дерева по принципу " левое поддерево - вершина - правое поддерево" . Разработать функции включения и получения значения элемента по заданному логическому номеру.
#include <stdio.h> #include <stdlib.h> #include <values.h> #define N 2 typedef struct tree { int *value; unsigned int size; struct tree **child; } TREE; TREE *CreateNode(unsigned int size) { TREE *new_node = (TREE *) malloc(sizeof(TREE)); new_node->value = (int *) malloc(sizeof(int) * size); new_node->size = size; new_node->child = (TREE **) malloc(sizeof(TREE) * 2); for(unsigned int i = 0; i < new_node->size; i++) *(new_node->value + i) = MAXINT; for(i = 0; i < 2; i++) *(new_node->child + i) = NULL; return (new_node); } TREE *found_node; unsigned int found_index; void ScanTreeIndex(TREE *node) { int found; if(node == NULL) return; for(unsigned int i = 0; i < 2; i++) if(node->child[i] == NULL) { if(found_node == NULL) { found = 0; for(unsigned int j = 0; j < node->size; j++) if(node->value[j] == MAXINT) { found = 1; break; } if(found) { found_node = node; found_index = j; break; } } else { if(node->size < found_node->size) { found = 0; for(unsigned int j = 0; j < node->size; j++) if(node->value[j] == MAXINT) { found = 1; break; } if(found) { found_node = node; found_index = j; break; } } } } for(i = 0; i < node->size; i++) ScanTreeIndex(node->child[i]); return; } void ScanTree(TREE *node) { if(node == NULL) return; for(unsigned int i = 0; i < 2; i++) if(node->child[i] == NULL) { if(found_node == NULL) { found_node = node; break; } else { if(node->size < found_node->size) { found_node = node; break; } } } for(i = 0; i < node->size; i++) ScanTree(node->child[i]); return; } TREE *InsertNode(TREE *root, int value) { TREE *new_node = NULL; if(root == NULL) { new_node = CreateNode(N); new_node->value[0] = value; return (new_node); } found_node = NULL; found_index = MAXINT; ScanTreeIndex(root); if((found_node != NULL) && (found_index != MAXINT)) found_node->value[found_index] = value; else { found_node = NULL; found_index = MAXINT; ScanTree(root); new_node = CreateNode(found_node->size * 2); new_node->value[0] = value; for(unsigned int i = 0; i < 2; i++) if(found_node->child[i] == NULL) { found_node->child[i] = new_node; break; } } return (new_node); } void main(void) { TREE * root = NULL; root = InsertNode(root, 1); InsertNode(root, 2); InsertNode(root, 3); InsertNode(root, 4); InsertNode(root, 5); InsertNode(root, 6); InsertNode(root, 7); //Добавьте здесь вывод того, что получается }
Список - каждый элемент является заголовком односвязного списка. Элемент списка второго уровня содержит указатель на строку. Включение и удаление по логическому номеру. Включение элемента последним в список производить с учетом выравнивания длины текущего и следующего списков. В этой программке даже печать есть :)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 3 typedef struct slavelist { char *value; struct slavelist *next; } SLAVELIST, *PSLAVELIST; typedef struct mainlist { PSLAVELIST slave; struct mainlist *next; } MAINLIST, *PMAINLIST; PSLAVELIST CreateSlave(char *value) { PSLAVELIST new_elem = (PSLAVELIST) malloc(sizeof(SLAVELIST)); new_elem->value = (char *) malloc(strlen(value) + 1); strcpy(new_elem->value, value); new_elem->next = NULL; return (new_elem); } PMAINLIST CreateMain(void) { PMAINLIST new_elem = (PMAINLIST) malloc(sizeof(MAINLIST)); new_elem->next = NULL; return (new_elem); } unsigned int GetSize(PMAINLIST elem) { unsigned int size = 0; PSLAVELIST slave_elem = elem->slave; while(slave_elem) { size++; slave_elem = slave_elem->next; } return (size); } unsigned int GetElementByNumberForAdd(PMAINLIST root, unsigned int number, PMAINLIST *pelem, PSLAVELIST *pslave_elem) { unsigned int counter = 0; PMAINLIST elem; PSLAVELIST slave_elem; *pelem = NULL; *pslave_elem = NULL; elem = root; while(elem) { slave_elem = elem->slave; while(slave_elem) { if(counter ++ == number - 1) { *pelem = elem; *pslave_elem = slave_elem; } slave_elem = slave_elem->next; } elem = elem->next; } return (counter); } unsigned int GetElementByNumberForDelete(PMAINLIST root, unsigned int number, PMAINLIST *pelem, PSLAVELIST *pslave_elem) { unsigned int counter = 0; PMAINLIST elem; PSLAVELIST slave_elem; *pelem = NULL; *pslave_elem = NULL; elem = root; while(elem) { slave_elem = elem->slave; while(slave_elem) { if(counter ++ == number) { *pelem = elem; *pslave_elem = slave_elem; } slave_elem = slave_elem->next; } elem = elem->next; } return (counter); } PSLAVELIST ScanListForAdd(PMAINLIST elem) { PSLAVELIST slave_elem = elem->slave; PSLAVELIST temp_slave_elem; while(slave_elem->next->next) slave_elem = slave_elem->next; temp_slave_elem = slave_elem->next; slave_elem->next = NULL; return (temp_slave_elem); } PMAINLIST AddNewElement(PMAINLIST root, char *value, unsigned int number) { PMAINLIST elem, temp_elem; PSLAVELIST slave_elem, found_slave_elem, new_slave_elem, temp_slave_elem; if((root == NULL) && (number != 0)) return (NULL); if(root == NULL) { elem = CreateMain(); new_slave_elem = CreateSlave(value); elem->slave = new_slave_elem; return (elem); } found_slave_elem = NULL; if(GetElementByNumberForAdd(root, number, &elem, &found_slave_elem) < number) return (NULL); new_slave_elem = CreateSlave(value); elem = root; if(found_slave_elem != NULL) { temp_slave_elem = found_slave_elem->next; found_slave_elem->next = new_slave_elem; new_slave_elem->next = temp_slave_elem; } else { temp_slave_elem = root->slave; root->slave = new_slave_elem; new_slave_elem->next = temp_slave_elem; } elem = root; temp_elem = NULL; while(elem) { if(GetSize(elem) > N) { temp_elem = elem; break; } elem = elem->next; } if(temp_elem != NULL) { temp_slave_elem = NULL; while(temp_elem) { if(GetSize(temp_elem) > N) { temp_slave_elem = ScanListForAdd(temp_elem); if(temp_slave_elem) { if(temp_elem->next) { temp_elem = temp_elem->next; found_slave_elem = temp_elem->slave; temp_elem->slave = temp_slave_elem; temp_slave_elem->next = found_slave_elem; continue; } else { elem = CreateMain(); elem->slave = temp_slave_elem; temp_elem->next = elem; break; } } } temp_elem = temp_elem->next; } } return (elem); } int DeleteElement(PMAINLIST *proot, unsigned int number) { PMAINLIST elem, temp_elem; PSLAVELIST slave_elem, temp_slave_elem; if(*proot == NULL) return (0); if(GetElementByNumberForDelete(*proot, number, &elem, &slave_elem) < number) return (0); if((*proot == elem) && ((*proot)->slave == slave_elem) && (slave_elem->next == NULL) && ((*proot)->next == NULL)) { delete slave_elem->value; delete slave_elem; delete *proot; *proot = NULL; return (1); } if(elem->slave == slave_elem) { elem->slave = slave_elem->next; delete slave_elem->value; delete slave_elem; if(elem->slave == NULL) { temp_elem = *proot; if(*proot == elem) *proot = elem->next; else { while(temp_elem->next != elem) temp_elem = temp_elem->next; temp_elem->next = elem->next; } delete elem; } } else { temp_slave_elem = elem->slave; while(temp_slave_elem->next != slave_elem) temp_slave_elem = temp_slave_elem->next; temp_slave_elem->next = slave_elem->next; delete slave_elem->value; delete slave_elem; } return (1); } void PrintAllLists(PMAINLIST root) { PMAINLIST elem; PSLAVELIST slave_elem; unsigned int count = 0; unsigned int count_slave = 0; elem = root; while(elem) { count++; printf("main element: %u\n", count); slave_elem = elem->slave; while(slave_elem) { printf("\tslave element: %s %d\n", slave_elem->value, count_slave ++); slave_elem = slave_elem->next; } elem = elem->next; } return; } void main(void) { PMAINLIST root = AddNewElement(NULL, "first", 0); AddNewElement(root, "second", 1); AddNewElement(root, "third", 2); AddNewElement(root, "fourth", 3); AddNewElement(root, "fifth", 4); AddNewElement(root, "sixth", 5); AddNewElement(root, "seventh", 5); PrintAllLists(root); DeleteElement(&root, 6); DeleteElement(&root, 0); PrintAllLists(root); return; }
гостевая; E-mail |