Saturday, 30 September 2017

c - Creating a binary search tree in C99



I've got a programming class assignment due tonight at 8 PM CDT that I'm having trouble with. We are to take a list of the following numbers via reading a file:



9
30
20
40
35
22
48
36
37
38



place them in an array (easy enough), and then read these into a binary search tree using C. The first number in the list is the number of elements in the tree. The rest are placed into the following struct:



typedef struct node_struct {
int data;
struct node_struct* left;
struct node_struct* right;
} Node;


I think I've got the first part down pat. Take the stuff in using fscanf (I didn't choose to use this method, I like fgets better), call an insertion function on each member of the array, then call a "createNode" function inside the insertion function.



Problem is, I'm only getting one member into the BST. Furthermore, the BST must satisfy the condition node->left->data <= node->data < node->right->data... in other words, the nodes must be in order in the tree.



Here's what I have so far:



#include 
#include
#include

// def BST node struct
typedef struct node_struct {
int data;
struct node_struct* left;
struct node_struct* right;
} Node;

// prototypes
Node* createNode(int data);
Node* bstInsert(Node* root, int data);
// helper function prototypes
void padding(char ch, int n);
void displayTree(Node* root, int depth);

int main(int argc, char **argv)
{
FILE *in = NULL;
int num_read, count=0, array_size = 0;

if(argc != 2){
printf("hw3 \n");
return 1;
}

in = fopen(argv[1], "r");

if(in == NULL){
printf("File can not be opened.\n");
return 2;
}

// read in the first line to get the array size
fscanf(in, "%d", &array_size);

// declare the array
int array[array_size];

// read from the second line to get each element of the array
while(!feof(in)){
fscanf(in, "%d", &num_read);
array[count] = num_read;
count++;
}
fclose(in);

if (array_size != count) {
printf("data error. Make sure the first line specifies the correct number of elements.");
return 3;
}

Node *root1 = NULL, *root2 = NULL, *root3 = NULL;

int i;
// task1: construct a bst from the unsorted array
printf("=== task1: construct a bst from the unsorted array ===\n");
for (i = 0; i < array_size; i++) {
root1 = bstInsert(root1, array[i]);
}
displayTree(root1, 0);
return 0;
}

Node* bstInsert(Node* root, int data) {
if(root == NULL){
root = createNode(data);

if(root != NULL){
root= createNode(data);
}

else{
printf("%d not inserted, no memory available.\n", data);
}
}

Node* current, previous, right;
current = root;
previous = root->left;
next = root->right;
else{
if(previous->data <= current->data){

}


}
return root;
}

Node* createNode(int data) {
// TODO
Node* aRoot;
if(!data)
return NULL;

aRoot = malloc(sizeof(Node));
if(!aRoot){
printf("Unable to allocate memory for node.\n");
return NULL;
}
aRoot->data = data;
aRoot->left = NULL;
aRoot->right = NULL;
return aRoot;
}

/* helper functions to print a bst; You just need to call displayTree when visualizing a bst */
void padding(char ch, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%c%c%c%c", ch, ch ,ch, ch);
}

void displayTree(Node* root, int depth){
if (root == NULL) {
padding (' ', depth);
printf("-\n");
}
else {
displayTree(root->right, depth+1);
padding(' ', depth);
printf ( "%d\n", root->data);
displayTree(root->left, depth+1);
}
}


main, createNode, displayTree, and padding are okay, I believe. It's bstInsert where I'm having trouble. I'm just not sure how to order things to create a valid tree.



EDIT:



I've edited bstInsert and injected some more logic. It should be printing out more leaves on the tree, but alas, it's only printing out the number "30". Here's the new function.



Node* bstInsert(Node* root, int data) {


if(root == NULL){
root = createNode(data);

if(root != NULL){
root= createNode(data);
}

else{
printf("%d not inserted, no memory available.\n", data);
}
}
else{
if(data < root->data){
bstInsert(root->left, data);
}
else if(data > root->data || data == root->data){
bstInsert(root->right, data);
}
}
return root;
}

Answer



You have to assign the newly created node pointer to the correct part of the tree. This code does that. The key change is using the return value from bstInsert() correctly. The other changes are cosmetic. Note that I checked the input array by printing it out; also, it is sensible to print out the BST as you build it.



Don't use feof() as a loop control condition. It is almost invariably wrong when used as a loop control, but at least you have to also check the input operation that follows. I've written a lot of programs in my time; I've hardly ever used feof() (I found two places in my own code with it; in both, it was correctly used to distinguish between EOF and an error after an input had failed.)



#include 
#include
#include

// def BST node struct
typedef struct node_struct
{
int data;
struct node_struct* left;
struct node_struct* right;
} Node;

// prototypes
Node *createNode(int data);
Node *bstInsert(Node *root, int data);
// helper function prototypes
void padding(char ch, int n);
void displayTree(Node *root, int depth);

int main(int argc, char **argv)
{
FILE *in = NULL;
int num_read, count=0, array_size = 0;

if (argc != 2)
{
printf("hw3 \n");
return 1;
}

in = fopen(argv[1], "r");

if (in == NULL)
{
printf("File can not be opened.\n");
return 2;
}

// read in the first line to get the array size
fscanf(in, "%d", &array_size);

// declare the array
int array[array_size];

// read from the second line to get each element of the array
while (count < array_size && fscanf(in, "%d", &num_read) == 1)
array[count++] = num_read;
fclose(in);

if (array_size != count)
{
printf("data error. Make sure the first line specifies the correct number of elements.");
return 3;
}

for (int i = 0; i < array_size; i++)
printf("%d: %d\n", i, array[i]);

Node *root1 = NULL;

// task1: construct a bst from the unsorted array
printf("=== task1: construct a bst from the unsorted array ===\n");

for (int i = 0; i < array_size; i++)
{
root1 = bstInsert(root1, array[i]);
displayTree(root1, 0);
}

displayTree(root1, 0);
return 0;
}

Node *bstInsert(Node *root, int data)
{
if (root == NULL)
{
root = createNode(data);
if (root == NULL)
printf("%d not inserted, no memory available.\n", data);
}
else if (data < root->data)
root->left = bstInsert(root->left, data);
else
root->right = bstInsert(root->right, data);
return root;
}

Node *createNode(int data)
{
Node *aRoot;

aRoot = malloc(sizeof(Node));
if (!aRoot)
{
printf("Unable to allocate memory for node.\n");
return NULL;
}
aRoot->data = data;
aRoot->left = NULL;
aRoot->right = NULL;
return aRoot;
}

/* helper functions to print a bst; You just need to call displayTree when visualizing a bst */
void padding(char ch, int n)
{
for (int i = 0; i < n; i++)
printf("%c%c%c%c", ch, ch, ch, ch);
}

void displayTree(Node *root, int depth)
{
if (root == NULL) {
padding (' ', depth);
printf("-\n");
}
else {
displayTree(root->right, depth+1);
padding(' ', depth);
printf ( "%d\n", root->data);
displayTree(root->left, depth+1);
}
}

No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...