193 lines
4.6 KiB
C
193 lines
4.6 KiB
C
#include "bintree.h"
|
|
#include "mymalloc.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
/* ------------------------- DO NOT IMPLEMENT THESE ----------------------
|
|
|
|
These are provided "free" to you, and you do not need to implement them,
|
|
though you MAY need to understand what they do. Some give you hints
|
|
on how to work with pointers to pointers. You MAY find some of these
|
|
functions useful.
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
// Searches for the node containing "name" in the tree whose root is at "root",
|
|
// returning both the node ifself in "node", and its parent in "prevnode"
|
|
// (useful for deleting node). Both "node" and "prevnode" are set to NULL
|
|
// if name is not found in the tree.
|
|
|
|
void findNode(char *name, TTreeNode *root, TTreeNode **node,
|
|
TTreeNode **prevnode) {
|
|
|
|
TTreeNode *trav = root;
|
|
TTreeNode *prev = NULL;
|
|
|
|
while (trav != NULL) {
|
|
int cmp = strcmp(trav->name, name);
|
|
|
|
if (cmp == 0) {
|
|
*node = trav;
|
|
*prevnode = prev;
|
|
return;
|
|
}
|
|
|
|
prev = trav;
|
|
if (cmp < 0)
|
|
trav = trav->right;
|
|
else
|
|
trav = trav->left;
|
|
}
|
|
|
|
*node = NULL;
|
|
*prevnode = NULL;
|
|
}
|
|
|
|
// Searches for the node with the smallest value ("smallest node") in the tree
|
|
// originating at "node". Returns the smallest node and its parent in
|
|
// "smallest_node" and "parent" respectively.
|
|
void findSmallest(TTreeNode *node, TTreeNode **smallest_node,
|
|
TTreeNode **parent) {
|
|
TTreeNode *trav = node;
|
|
TTreeNode *prev = NULL;
|
|
|
|
if (trav == NULL)
|
|
return;
|
|
|
|
while (trav->left != NULL) {
|
|
prev = trav;
|
|
trav = trav->left;
|
|
}
|
|
|
|
*smallest_node = trav;
|
|
*parent = prev;
|
|
}
|
|
|
|
// Delete a node at "node" with parent node "prevnode"
|
|
void delNode(TTreeNode *node, TTreeNode *prevnode) {
|
|
// This is a leaf node
|
|
if (node->left == NULL && node->right == NULL) {
|
|
// See whether node is on parent's left or right, and NULL the
|
|
// corresponding pointer
|
|
|
|
int cmp = strcmp(prevnode->name, node->name);
|
|
|
|
// Previous node is smaller than this one. This
|
|
// node is on the right
|
|
if (cmp < 0)
|
|
prevnode->right = NULL;
|
|
else
|
|
prevnode->left = NULL;
|
|
|
|
freenode(node);
|
|
|
|
return;
|
|
}
|
|
|
|
// This has a child on the left only
|
|
if (node->right == NULL) {
|
|
// Copy the right child over
|
|
node = node->left;
|
|
freenode(node->left);
|
|
return;
|
|
}
|
|
|
|
// This has a child on the right only
|
|
if (node->left == NULL) {
|
|
node = node->right;
|
|
freenode(node->right);
|
|
return;
|
|
}
|
|
|
|
// This has children on both nodes
|
|
TTreeNode *smallest, *smallest_parent;
|
|
findSmallest(node->right, &smallest, &smallest_parent);
|
|
node = smallest;
|
|
smallest_parent->left = NULL;
|
|
freenode(smallest);
|
|
}
|
|
|
|
/* ---------------------------- IMPLEMENT THESE --------------------------- */
|
|
|
|
// Create a new node with name set to "name" and
|
|
// phoneNum set to "phoneNum".
|
|
void delTree(TTreeNode *root) {
|
|
// Implement deleting the entire tree, whose
|
|
// root is at "root".
|
|
if (root == NULL)
|
|
return;
|
|
if (root->left != NULL)
|
|
delTree(root->left);
|
|
if (root->right != NULL)
|
|
delTree(root->right);
|
|
freenode(root);
|
|
}
|
|
|
|
TTreeNode *makeNewNode(char *name, char *phoneNum) {
|
|
TTreeNode *node = mymalloc(sizeof(TTreeNode));
|
|
node->name = mymalloc(strlen(name) + 1);
|
|
strcpy(node->name, name);
|
|
strcpy(node->phoneNum, phoneNum);
|
|
node->left = NULL;
|
|
node->right = NULL;
|
|
return node;
|
|
// Implement makeNewNode to create a new
|
|
// TTreeNode containing name and phoneNum
|
|
}
|
|
|
|
// Add a new node to the tree.
|
|
// Note that "root" is a POINTER to the tree's root,
|
|
// not the root itself.
|
|
|
|
void addNode(TTreeNode **root, TTreeNode *node) {
|
|
if (*root == NULL) {
|
|
*root = node;
|
|
}
|
|
|
|
TTreeNode **trav = root;
|
|
|
|
while (1) {
|
|
|
|
int cmp = strcmp((*trav)->name, node->name);
|
|
if (cmp == 0)
|
|
return;
|
|
if (cmp > 0) {
|
|
if ((*trav)->left == NULL)
|
|
(*trav)->left = node;
|
|
else {
|
|
trav = &((*trav)->left);
|
|
continue;
|
|
}
|
|
} else if (cmp < 0) {
|
|
if ((*trav)->right == NULL)
|
|
(*trav)->right = node;
|
|
else {
|
|
trav = &((*trav)->right);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add a new node to the tree, where root is
|
|
// the POINTER to the tree's root.
|
|
}
|
|
|
|
void freenode(TTreeNode *node) {
|
|
myfree(node->name);
|
|
myfree(node);
|
|
// Frees the memory used by node.
|
|
}
|
|
|
|
void print_inorder(TTreeNode *node) {
|
|
// Implement in-order printing of the tree
|
|
// Recursion is probably best here.
|
|
|
|
if (node == NULL)
|
|
return;
|
|
if (node->left != NULL)
|
|
print_inorder(node->left);
|
|
printf("Name is %s Number is %s\n", node->name, node->phoneNum);
|
|
if (node->right != NULL)
|
|
print_inorder(node->right);
|
|
}
|