Sunteți pe pagina 1din 13

Ministerul Educaţiei, Culturii și Cercetării al

RepubliciiMoldova

Universitatea Tehnică a Moldovei

RAPORT
Lucrarea de laborator nr. 4
la Structuri De Date Si Algoritmi

A efectuat: st. gr. TI-224 Revenko Ivan

A verificat: Bîrnaz Adrian


UTM, Chișinău 2023

Lucrare de laborator
la disciplina
Structuri de Date și Algoritmi
Lucrare de laborator nr. 4:

Tema:
Implementarea tipului de date abstract “Arbore binar de căutare” în limbajul C.

Scopul lucrării
Scopul lucrării este de a familiariza studentul cu mecanismul de creare a arborelui binar
de căutare și operații elementare asupra acestuia, utilizînd pentru aceasta limbajul C.
Problema

1. Să se elaboreze un program ce va aloca dinamic un arbore de căutare binar de


structuri (unde structurile vor fi cu mai multe cîmpuri, minim 4 cîmpuri, dintre
care un cîmp pentru cheie numit key) și va realiza următoarele funcții, unde
funcțiile date reprezintă opțiuni organizate într-un meniu în cadrul programului:
- citirea de la tastatură a elementelor arborelui;
- afișarea la consolă a elementelor arborelui;
- căutarea unui nod în baza cîmpului cheie și afișarea cîmpurilor nodului găsit;
- parcurgerea arborelui în inordine;
- parcurgerea arborelui în preordine;
- parcurgerea arborelui în postordine;
- parcurgerea arborelui în adîncime( DFS);
- parcurgerea arborelui în lărgime ( BFS);
- balansarea arborelui (în imaginea de mai jos este redat un arbore balansat și unul
nebalansat );
- oglindirea arborelui (orice nod copil drept, devine un nod copil stîng și analog orice nod
copil stîng devine un nod copil drept), ține cont că după oglindirea arborelui binar de
căutare proprietatea între nod și copii se va schimba, prin urmare și căutarea deja se va
face în altă ordine;
- curățirea elementelor arborelui;
- eliberarea memoriei arborelui.
Codul:

#include <stdio.h>
#include <stdlib.h>
#define MAX_QUEUE_SIZE 100
struct node
{
int key;
struct node *left, *right;
};
struct node *root = NULL;
// Create a node
struct node *newNode(int item)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// Inorder Traversal
void inorder(struct node *root)
{
if (root != NULL)
{
// Traverse left
inorder(root->left);
// Traverse root
printf("%d ", root->key);
// Traverse right
inorder(root->right);
}
}
// Insert a node
struct node *insert(struct node *node, int key)
{
// Return a new node if the tree is empty
if (node == NULL)
return newNode(key);
// Traverse to the right place and insert the node
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
return node;
}
// Find the inorder successor
struct node *minValueNode(struct node *node)
{
struct node *current = node;
// Find the leftmost leaf
while (current && current->left != NULL)
current = current->left;
return current;
}
// Deleting a node
struct node *deleteNode(struct node *root, int key)
{
// Return if the tree is empty
if (root == NULL)
return root;
// Find the node to be deleted
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else
{
// If the node is with only one child or no child
if (root->left == NULL)
{
struct node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
struct node *temp = root->left;
free(root);
return temp;
}
// If the node has two children
struct node *temp = minValueNode(root->right);
// Place the inorder successor in position of the node to be deleted
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
return root;
}
void createTree()
{
printf("Number of nodes: ");
int n, k;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
printf("key of node %d: ", i);
scanf("%d", &k);
root = insert(root, k);
}
}
void preorder(struct node *root)
{
if (root != NULL)
{
printf("%d ", root->key);
preorder(root->left);
preorder(root->right);
}
}
void postorder(struct node *root)
{
if (root != NULL)
{
postorder(root->left);
postorder(root->right);
printf("%d ", root->key);
}
}
void printTree(struct node *root, int level) // inorder
{
if (root == NULL)
{
return;
}
printTree(root->right, level + 1);
for (int i = 0; i < level; i++)
{
printf(" ");
}
printf("%d\n", root->key);
printTree(root->left, level + 1);
}
void searchAndPrintNode(struct node *root, int key)
{
// If the root is null or the key is found at the root, print the root's key vand
return
if (root == NULL || root->key == key)
{
if (root != NULL)
{
printf("Found node with key %d\n", root->key);
if (root->left != NULL)
{
printf("Left neighbor: %d\n", root->left->key);
}
else
{
printf("Left neighbor does not exist\n");
}
if (root->right != NULL)
{
printf("Right neighbor: %d\n", root->right->key);
}
else
{
printf("Right neighbor does not exist\n");
}
}
else
{
printf("Node with key %d not found\n", key);
}
return;
}
// If the key is less than the root's key, search in the left subtree
if (key < root->key)
{
searchAndPrintNode(root->left, key);
}
// If the key is greater than the root's key, search in the right subtree
else
{
searchAndPrintNode(root->right, key);
}
}
void dfs(struct node *root)
{
if (root == NULL)
{
return;
}
printf("%d ", root->key);
if (root->left != NULL)
{
dfs(root->left);
}
if (root->right != NULL)
{
dfs(root->right);
}
}
typedef struct Queue
{
struct node *items[MAX_QUEUE_SIZE];
int front;
int rear;
} Queue;
void enqueue(Queue *q, struct node *item)
{
if (q->rear == MAX_QUEUE_SIZE - 1)
{
printf("Queue Overflow\n");
exit(EXIT_FAILURE);
}
q->rear++;
q->items[q->rear] = item;
}
struct node *dequeue(Queue *q)
{
if (q->front == q->rear)
{
printf("Queue Underflow\n");
exit(EXIT_FAILURE);
}
q->front++;
return q->items[q->front];
}
int is_empty(Queue *q)
{
return q->front == q->rear;
}
void bfs(struct node *root)
{
Queue q;
q.front = -1;
q.rear = -1;
enqueue(&q, root);
while (!is_empty(&q))
{
struct node *current = dequeue(&q);
printf("%d ", current->key);
if (current->left != NULL)
{
enqueue(&q, current->left);
}
if (current->right != NULL)
{
enqueue(&q, current->right);
}
}
}
struct node *createNode(int key)
{
struct node *newNode = (struct node *)malloc(sizeof(struct node));
newNode->key = key;
newNode->left = newNode->right = NULL;
return newNode;
}
void storeInorder(struct node *root, int *arr, int *index)
{
if (root == NULL)
{
return;
}
storeInorder(root->left, arr, index);
arr[(*index)++] = root->key;
storeInorder(root->right, arr, index);
}
struct node *sortedArrayToBST(int *arr, int start, int end)
{
if (start > end)
{
return NULL;
}
int mid = (start + end) / 2;
struct node *root = createNode(arr[mid]);
root->left = sortedArrayToBST(arr, start, mid - 1);
root->right = sortedArrayToBST(arr, mid + 1, end);
return root;
}
// Function to convert a normal BST to a balanced BST
struct node *balanceBST(struct node *root)
{
// Store the BST keys in an array in-order
int arr[1000], index = 0;
storeInorder(root, arr, &index);
// Create a balanced BST from the sorted array
return sortedArrayToBST(arr, 0, index - 1);
}
void mirrorBST(struct node *root)
{
if (root == NULL)
{
return;
}
struct node *temp = root->left;
root->left = root->right;
root->right = temp;
mirrorBST(root->left);
mirrorBST(root->right);
}
void cleanBST(struct node *root)
{
if (root == NULL)
{
return;
}
cleanBST(root->left);
cleanBST(root->right);
free(root);
}
void freeBST(struct node *root)
{
cleanBST(root);
root = NULL;
}
void menu()
{
int option;
printf("\nMenu: \n");
printf("1. Create a BS tree:\n");
printf("2. Print the BS tree:\n");
printf("3. Search a node by key:\n");
printf("4. Preorder:\n");
printf("5. Inorder:\n");
printf("6. Postorder:\n");
printf("7. DFS:\n");
printf("8. BFS:\n");
printf("9. Balance the tree:\n");
printf("10. Mirrored tree:\n");
printf("11. Clean tree elements:\n");
printf("12. Free tree memory:\n");
printf("Menu option: ");
scanf("%d", &option);
switch (option)
{
case 1:
createTree();
menu();
break;
case 2:
if (root == NULL)
{
printf("Please enter a tree");
}
else
{
printTree(root, 0);
}
menu();
break;
case 3:
printf("Introduce the key to search:");
int searchBy;
scanf("%d", searchBy);
searchAndPrintNode(root, searchBy);
break;
case 4:
printf("Preorder traversal: ");
preorder(root);
menu();
break;
case 5:
printf("Inorder traversal: ");
inorder(root);
menu();
break;
case 6:
printf("Postorder traversal: ");
postorder(root);
menu();
break;
case 7:
printf("DFS: ");
dfs(root);
menu();
break;
case 8:
printf("BFS: ");
bfs(root);
menu();
break;
case 9:
printf("Balanced tree:\n");
root = balanceBST(root);
printTree(root, 0);
menu();
break;
case 10:
printf("Mirrored tree:\n");
mirrorBST(root);
printTree(root, 0);
menu();
break;
case 11:
cleanBST(root);
printf("Tree elements are cleared\n");
menu();
break;
case 12:
freeBST(root);
printf("Tree memory is freed\n");
menu();
break;
default:
break;
}
}
int main()
{
menu();
return 0;
}
Concluzie:
In urma acestei lucrari de laborator m-am familiarizat cu tipul de date abstract “Arbore
binar de căutare” in limbajul C.

S-ar putea să vă placă și