Documente Academic
Documente Profesional
Documente Cultură
RepubliciiMoldova
RAPORT
Lucrarea de laborator nr. 4
la Structuri De Date Si Algoritmi
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
#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.