feat: last part of 2106 lab4
This commit is contained in:
parent
9183d82953
commit
fe0a63b2ba
192
labs/cs2106/labs/lab4/linkedlist/pb/bintree.c
Normal file
192
labs/cs2106/labs/lab4/linkedlist/pb/bintree.c
Normal file
@ -0,0 +1,192 @@
|
||||
#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);
|
||||
}
|
17
labs/cs2106/labs/lab4/linkedlist/pb/bintree.h
Normal file
17
labs/cs2106/labs/lab4/linkedlist/pb/bintree.h
Normal file
@ -0,0 +1,17 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct tn {
|
||||
char *name;
|
||||
char phoneNum[9];
|
||||
struct tn *left, *right;
|
||||
} TTreeNode;
|
||||
|
||||
void findNode(char *, TTreeNode *, TTreeNode **, TTreeNode **);
|
||||
void findSmallest(TTreeNode *, TTreeNode **, TTreeNode **);
|
||||
void delNode(TTreeNode *, TTreeNode *);
|
||||
void delTree(TTreeNode *);
|
||||
TTreeNode *makeNewNode(char *, char *);
|
||||
void addNode(TTreeNode **, TTreeNode *);
|
||||
void freenode(TTreeNode *);
|
||||
void print_inorder(TTreeNode *);
|
239
labs/cs2106/labs/lab4/linkedlist/pb/llist.c
Normal file
239
labs/cs2106/labs/lab4/linkedlist/pb/llist.c
Normal file
@ -0,0 +1,239 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
//#define DEBUG // Enable debug printing
|
||||
|
||||
// Debug printer
|
||||
|
||||
void dbprintf(char *format, ...) {
|
||||
#ifdef DEBUG
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Implements a double linked list.
|
||||
|
||||
// Create a new node. You need to
|
||||
// Create your own TData node, populate
|
||||
// it, then create a new node with a suitable
|
||||
// key. Insertion into the link list is
|
||||
// by ascending order of the key. An example key
|
||||
// might be the starting address of a memory segment.
|
||||
|
||||
TNode *make_node(unsigned int key, TData *data) {
|
||||
TNode *node = malloc(sizeof(TNode));
|
||||
node->key = key;
|
||||
node->pdata = data;
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// Inserts a node into the correct point of the
|
||||
// double linked list. The list is sorted
|
||||
// in ascending order of the key. Duplicate keys
|
||||
// are permitted, though not recommended.
|
||||
// llist = Pointer to link list
|
||||
// node = Pointer to node created by make_node
|
||||
// dir = 0: Insert in ascending order
|
||||
// dir = 1: Insert in descending order
|
||||
|
||||
void insert_node(TNode **llist, TNode *node, int dir) {
|
||||
if(*llist == NULL) {
|
||||
*llist = node;
|
||||
(*llist)->trav = *llist;
|
||||
(*llist)->tail = *llist;
|
||||
}
|
||||
else
|
||||
if(((*llist)->key >= node->key && dir == 0) || (((*llist)->key <= node->key) && dir == 1)) {
|
||||
node->next = *llist;
|
||||
(*llist)->prev = node;
|
||||
*llist = node;
|
||||
(*llist)->trav = *llist;
|
||||
}
|
||||
else
|
||||
{
|
||||
TNode *trav = *llist;
|
||||
|
||||
if(dir == 0)
|
||||
while(trav->next != NULL && trav->key < node->key)
|
||||
trav = trav->next;
|
||||
else if(dir == 1)
|
||||
while(trav->next != NULL && trav->key > node->key)
|
||||
trav = trav->next;
|
||||
|
||||
if(trav->next == NULL && ((trav->key < node->key && dir == 0) ||
|
||||
(trav->key > node->key && dir == 1))) {
|
||||
trav->next = node;
|
||||
node->prev = trav;
|
||||
|
||||
// Set the tail
|
||||
(*llist)->tail = node;
|
||||
} else {
|
||||
// Insert into the previous space
|
||||
|
||||
node->next = trav;
|
||||
|
||||
if(trav->prev != NULL) {
|
||||
trav->prev->next = node;
|
||||
node->prev = trav->prev;
|
||||
}
|
||||
|
||||
if(trav->next != NULL) {
|
||||
}
|
||||
|
||||
trav->prev = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a given node from the linked list
|
||||
void delete_node(TNode **llist, TNode *node) {
|
||||
|
||||
if(*llist == NULL || node == NULL)
|
||||
return;
|
||||
|
||||
if((*llist)->key == node->key) {
|
||||
// Node to be deleted is at the front of the list.
|
||||
*llist = (*llist)->next;
|
||||
|
||||
// Ensure that we don't point to it anymore.
|
||||
if(*llist != NULL)
|
||||
(*llist)->prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
TNode *trav = *llist;
|
||||
|
||||
while(trav != NULL && trav->key != node->key)
|
||||
trav = trav->next;
|
||||
|
||||
// We've found the deletion point
|
||||
if(trav != NULL) {
|
||||
trav->prev->next = trav->next;
|
||||
|
||||
if(trav->next != NULL)
|
||||
trav->next->prev = trav->prev;
|
||||
else
|
||||
(*llist)->tail = trav->prev;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
// Find a node that has the value of key
|
||||
// If there are duplicate keys, the first one encountered
|
||||
// will be returned.
|
||||
TNode *find_node(TNode *llist, unsigned int key) {
|
||||
if(llist == NULL)
|
||||
return NULL;
|
||||
|
||||
TNode *trav = llist;
|
||||
|
||||
while(trav != NULL && trav->key != key)
|
||||
trav = trav->next;
|
||||
|
||||
return trav;
|
||||
}
|
||||
|
||||
// Merge the node provided with either the node after or the node before.
|
||||
// You need to manage merging the data in node->pdata yourself. This code just
|
||||
// deletes the larger of the two nodes.
|
||||
// dir = 0: Merge with node before
|
||||
// dir = 1: Merge with node after
|
||||
|
||||
void merge_node(TNode *llist, TNode *node, int dir) {
|
||||
if(dir == 0) {
|
||||
if(node->prev == NULL)
|
||||
return;
|
||||
|
||||
delete_node(&llist, node);
|
||||
}
|
||||
else
|
||||
if(dir == 1) {
|
||||
if(node->next == NULL)
|
||||
return;
|
||||
|
||||
delete_node(&llist, node->next);
|
||||
}
|
||||
}
|
||||
|
||||
// Go over every element of llist, and call func
|
||||
// func prototype is void func(TNode *);
|
||||
|
||||
void process_list(TNode *llist, void (*func)(TNode *)) {
|
||||
TNode *trav = llist;
|
||||
while(trav) {
|
||||
func(trav);
|
||||
trav = trav->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Purge the entire list. You must
|
||||
// free any dynamic data in the TData
|
||||
// struct yourself.
|
||||
void purge_list(TNode **llist) {
|
||||
TNode *trav = *llist, *tmp;
|
||||
while(trav) {
|
||||
tmp = trav->next;
|
||||
free(trav);
|
||||
trav = tmp;
|
||||
}
|
||||
|
||||
*llist = NULL;
|
||||
}
|
||||
|
||||
|
||||
// Reset traverser
|
||||
// where=0 START: Resets traverser to start of list
|
||||
// where=1 END: Rsets
|
||||
void reset_traverser(TNode *llist, int where)
|
||||
{
|
||||
if(llist == NULL)
|
||||
return;
|
||||
|
||||
if(where == FRONT)
|
||||
llist->trav = llist;
|
||||
else
|
||||
if(where == REAR)
|
||||
llist->trav = llist->tail;
|
||||
}
|
||||
|
||||
// Get the next node
|
||||
TNode *succ(TNode *llist)
|
||||
{
|
||||
if(llist == NULL)
|
||||
return NULL;
|
||||
|
||||
TNode *ret = llist->trav;
|
||||
|
||||
if(llist->trav != NULL)
|
||||
llist->trav = llist->trav->next;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the previous node
|
||||
TNode *pred(TNode *llist)
|
||||
{
|
||||
if(llist == NULL)
|
||||
return NULL;
|
||||
|
||||
TNode *ret = llist->trav;
|
||||
|
||||
if(llist->trav != NULL)
|
||||
llist->trav = llist->trav->prev;
|
||||
|
||||
return ret;
|
||||
}
|
115
labs/cs2106/labs/lab4/linkedlist/pb/llist.h
Normal file
115
labs/cs2106/labs/lab4/linkedlist/pb/llist.h
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Uncomment the next line to enable debug printing
|
||||
#define DEBUG // Enable debug printing
|
||||
|
||||
// The debug printer; used like a normal printf, except
|
||||
// that printing can be turned off by commenting out the
|
||||
// #define DEBUG above.
|
||||
void dbprintf(char *format, ...);
|
||||
|
||||
// You should modify this structure to hold
|
||||
// whatever you need to implement your
|
||||
// memory manager. You can delete the
|
||||
// val field. It is only used for testlist.c
|
||||
|
||||
typedef struct td {
|
||||
bool occupied;
|
||||
size_t size;
|
||||
} TData;
|
||||
|
||||
/* -----------------------------------------
|
||||
BASIC ROUTINES
|
||||
|
||||
Basic linked list routines
|
||||
|
||||
---------------------------------------- */
|
||||
|
||||
// Basic double linked list node.
|
||||
|
||||
typedef struct tn {
|
||||
unsigned int key;
|
||||
TData *pdata; // Pointer to the data you want to store
|
||||
|
||||
struct tn *trav; // Only used in the root for traversal
|
||||
struct tn *tail; // Only used in the root for finding the end of the list
|
||||
struct tn *prev;
|
||||
struct tn *next;
|
||||
} TNode;
|
||||
|
||||
// Insert Direction
|
||||
#define ASCENDING 0
|
||||
#define DESCENDING 1
|
||||
|
||||
// Merge direction
|
||||
#define PRECEDING 0
|
||||
#define SUCCEEDING 1
|
||||
|
||||
// Traverser position
|
||||
#define FRONT 0
|
||||
#define REAR 1
|
||||
|
||||
// Create a new node. You need to
|
||||
// Create your own TData node, populate
|
||||
// it, then create a new node with a suitable
|
||||
// key. Insertion into the link list is
|
||||
// by ascending order of the key. An example key
|
||||
// might be the starting address of a memory segment.
|
||||
|
||||
TNode *make_node(unsigned int key, TData *data);
|
||||
|
||||
// Inserts a node into the correct point of the
|
||||
// double linked list. The list is sorted
|
||||
// in ascending order of the key. Duplicate keys
|
||||
// are permitted, though not recommended.
|
||||
// llist = Pointer to link list
|
||||
// node = Pointer to node created by make_node
|
||||
// dir = 0: Insert in ascending order
|
||||
// dir = 1: Insert in descending order
|
||||
|
||||
void insert_node(TNode **llist, TNode *node, int dir);
|
||||
|
||||
// Remove a given node from the linked list
|
||||
void delete_node(TNode **llist, TNode *node);
|
||||
|
||||
// Find a node that has the value of key
|
||||
// If there are duplicate keys, the first one encountered
|
||||
// will be returned.
|
||||
TNode *find_node(TNode *llist, unsigned int key);
|
||||
|
||||
// Merge the node provided with either the node after or the node before.
|
||||
// You need to manage merging the data in node->pdata yourself. This code just
|
||||
// deletes the larger of the two nodes.
|
||||
// dir = 0: Merge with node before
|
||||
// dir = 1: Merge with node after
|
||||
|
||||
void merge_node(TNode *llist, TNode *node, int dir);
|
||||
|
||||
// Purge the entire list. You must
|
||||
// free any dynamic data in the TData
|
||||
// struct yourself.
|
||||
void purge_list(TNode **llist);
|
||||
|
||||
/* -----------------------------------------
|
||||
TRAVERSAL ROUTINES
|
||||
|
||||
Lets you traverse the linked list
|
||||
|
||||
---------------------------------------- */
|
||||
|
||||
// Go over every element of llist, and call func
|
||||
// func prototype is void func(TNode *);
|
||||
|
||||
void process_list(TNode *llist, void (*func)(TNode *));
|
||||
|
||||
// Reset traverser
|
||||
// where=0 START: Resets traverser to start of list
|
||||
// where=1 END: Rsets
|
||||
void reset_traverser(TNode *llist, int where);
|
||||
|
||||
// Get the next node
|
||||
TNode *succ(TNode *llist);
|
||||
|
||||
// Get the previous node
|
||||
TNode *pred(TNode *llist);
|
103
labs/cs2106/labs/lab4/linkedlist/pb/mymalloc.c
Normal file
103
labs/cs2106/labs/lab4/linkedlist/pb/mymalloc.c
Normal file
@ -0,0 +1,103 @@
|
||||
#include "mymalloc.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/_types/_null.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
char _heap[MEMSIZE] = {0};
|
||||
TNode *_memlist = NULL; // To maintain information about length
|
||||
|
||||
// Do not change this. Used by the test harness.
|
||||
// You may however use this function in your code if necessary.
|
||||
long get_index(void *ptr) {
|
||||
if (ptr == NULL)
|
||||
return -1;
|
||||
else
|
||||
return (long)((char *)ptr - &_heap[0]);
|
||||
}
|
||||
|
||||
// Allocates size bytes of memory and returns a pointer
|
||||
// to the first byte.
|
||||
void *mymalloc(size_t size) {
|
||||
if (_memlist == NULL) {
|
||||
TData *data = malloc(sizeof(TData));
|
||||
data->occupied = false;
|
||||
data->size = MEMSIZE;
|
||||
_memlist = make_node(0, data);
|
||||
}
|
||||
|
||||
// loop through the list to find a free block
|
||||
// if found, split the block and return the pointer
|
||||
// if not found, return NULL
|
||||
TNode *curr = _memlist;
|
||||
TNode *best = NULL;
|
||||
while (curr != NULL) {
|
||||
if (curr->pdata->occupied == true) {
|
||||
curr = curr->next;
|
||||
continue;
|
||||
}
|
||||
if (curr->pdata->size < size) {
|
||||
curr = curr->next;
|
||||
continue;
|
||||
}
|
||||
if (best == NULL) {
|
||||
best = curr;
|
||||
curr = curr->next;
|
||||
continue;
|
||||
}
|
||||
if (best->pdata->size > curr->pdata->size) {
|
||||
best = curr;
|
||||
curr = curr->next;
|
||||
continue;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
if (best == NULL)
|
||||
return NULL;
|
||||
best->pdata->occupied = true;
|
||||
if (best->pdata->size > size) {
|
||||
// Create a new node with the leftover space
|
||||
TData *newData = malloc(sizeof(TData));
|
||||
newData->occupied = false;
|
||||
newData->size = best->pdata->size - size;
|
||||
TNode *newNode = make_node(best->key + size, newData);
|
||||
// insert new node after the current one in the list.
|
||||
insert_node(&_memlist, newNode, 0);
|
||||
// change the size of the current node.
|
||||
best->pdata->size = size;
|
||||
}
|
||||
return &_heap[best->key];
|
||||
}
|
||||
|
||||
// Frees memory pointer to by ptr.
|
||||
void myfree(void *ptr) {
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
long index = get_index(ptr);
|
||||
TNode *node = find_node(_memlist, index);
|
||||
if (node == NULL)
|
||||
return;
|
||||
node->pdata->occupied = false;
|
||||
// merge with the next node if it is free
|
||||
while (node->next != NULL && node->next->pdata->occupied == false) {
|
||||
node->pdata->size += node->next->pdata->size;
|
||||
merge_node(_memlist, node, 1);
|
||||
}
|
||||
|
||||
while (node->prev != NULL && node->prev->pdata->occupied == false) {
|
||||
TNode *prev = node->prev;
|
||||
prev->pdata->size += node->pdata->size;
|
||||
merge_node(_memlist, node, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void print_node(TNode *node) {
|
||||
printf("Status: %s Start index: %d Length: %zu\n",
|
||||
node->pdata->occupied ? "ALLOCATED" : "FREE", node->key,
|
||||
node->pdata->size);
|
||||
}
|
||||
|
||||
void print_memlist() { process_list(_memlist, print_node); }
|
7
labs/cs2106/labs/lab4/linkedlist/pb/mymalloc.h
Normal file
7
labs/cs2106/labs/lab4/linkedlist/pb/mymalloc.h
Normal file
@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#define MEMSIZE 64 * 1024 // Size of memory in bytes
|
||||
|
||||
long get_index(void *ptr);
|
||||
void print_memlist();
|
||||
void *mymalloc(size_t);
|
||||
void myfree(void *);
|
51
labs/cs2106/labs/lab4/linkedlist/pb/phonebook.c
Normal file
51
labs/cs2106/labs/lab4/linkedlist/pb/phonebook.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include "phonebook.h"
|
||||
#include "bintree.h"
|
||||
|
||||
static TTreeNode *_root = NULL;
|
||||
|
||||
char *findPerson(char *name)
|
||||
{
|
||||
TTreeNode *node, *prev;
|
||||
findNode(name, _root, &node, &prev);
|
||||
|
||||
if (node != NULL)
|
||||
return node->phoneNum;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void print_phonebook()
|
||||
{
|
||||
print_inorder(_root);
|
||||
}
|
||||
|
||||
void addPerson(char *name, char *phoneNum)
|
||||
{
|
||||
if (findPerson(name) == NULL)
|
||||
{
|
||||
TTreeNode *node = makeNewNode(name, phoneNum);
|
||||
addNode(&_root, node);
|
||||
}
|
||||
else
|
||||
printf("%s is already in phonebook.\n", name);
|
||||
}
|
||||
|
||||
void delPerson(char *name)
|
||||
{
|
||||
TTreeNode *node, *prevnode;
|
||||
findNode(name, _root, &node, &prevnode);
|
||||
if (node == NULL)
|
||||
{
|
||||
printf("Unable to find %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
delNode(node, prevnode);
|
||||
}
|
||||
|
||||
void delPhonebook()
|
||||
{
|
||||
delTree(_root);
|
||||
_root = NULL;
|
||||
}
|
5
labs/cs2106/labs/lab4/linkedlist/pb/phonebook.h
Normal file
5
labs/cs2106/labs/lab4/linkedlist/pb/phonebook.h
Normal file
@ -0,0 +1,5 @@
|
||||
char *findPerson(char *);
|
||||
void addPerson(char *, char *);
|
||||
void delPerson(char *);
|
||||
void print_phonebook();
|
||||
void delPhonebook();
|
60
labs/cs2106/labs/lab4/linkedlist/pb/testpb.c
Normal file
60
labs/cs2106/labs/lab4/linkedlist/pb/testpb.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include <stdio.h>
|
||||
#include "phonebook.h"
|
||||
|
||||
#define ITEMS 5
|
||||
|
||||
typedef struct d
|
||||
{
|
||||
char *name, *tel;
|
||||
} TData;
|
||||
|
||||
void printResult(char *name)
|
||||
{
|
||||
char *result;
|
||||
|
||||
printf("Looking for %s ", name);
|
||||
result = findPerson(name);
|
||||
if (result == NULL)
|
||||
printf("NOT FOUND\n");
|
||||
else
|
||||
printf(" Number is %s\n", result);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TData data[ITEMS] = {{"Fred Astaire", "95551234"}, {"Jean Valjean", "95558764"}, {"Gal Gadot", "95551123"}, {"Aiken Dueet", "95558876"}, {"Victor Hugo", "95524601"}};
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ITEMS; i++)
|
||||
{
|
||||
printf("Adding %s, phone number %s\n", data[i].name, data[i].tel);
|
||||
addPerson(data[i].name, data[i].tel);
|
||||
}
|
||||
|
||||
printf("\nNow retrieiving stored data.\n");
|
||||
char *result;
|
||||
|
||||
for (i = 0; i < ITEMS; i++)
|
||||
{
|
||||
printResult(data[i].name);
|
||||
}
|
||||
|
||||
printf("\nRetrieving unknown person.\n");
|
||||
printResult("Wee Tu Loh");
|
||||
|
||||
printf("\nPrinting entire phonebook.\n");
|
||||
print_phonebook();
|
||||
|
||||
printf("\nDeleting Aiken Dueet.\n");
|
||||
delPerson("Aiken Dueet");
|
||||
print_phonebook();
|
||||
|
||||
printf("\nDeleting Victor Hugo.\n");
|
||||
delPerson("Victor Hugo");
|
||||
print_phonebook();
|
||||
|
||||
printf("\nDeleting entire phone book.\n");
|
||||
delPhonebook();
|
||||
print_phonebook();
|
||||
}
|
Loading…
Reference in New Issue
Block a user