NULL assignment to a structure pointer is not working through function. What to do? - c

I am trying to implement BST deletion. According to algorithm, we can delete a leaf directly. Now I'm assigning NULL to leaf directly and still this node remains as it is.
In the test case I gave tried to delete leaf and it is not working.
Please help!
struct node * delet(long data, struct node* root)
{
int i=1;
struct node *temp = root,*t;
while(temp != 0)
{
if(data < temp->data)
{
i=2*i;
temp = temp->l;
}
else if(data > temp->data)
{
i = (2*i)+1;
temp = temp->r ;
}
else
{
printf("%d\n",i);
break;
}
}
if(temp->l == 0 && temp->r == 0)
{
temp = 0;
return root;
}
else if(temp->l == 0)
{
temp->data = temp->l->data;
temp->l = 0;
}
else if(temp->r == 0)
{
temp->data = temp->r->data;
temp->r = 0;
}
else
{
t = temp;
t = t->r;
while(t->l != 0)
{
t = t->l;
}
temp->data = t->data;
if(t->r != 0)
{
t->data = t->r->data;
t->r = 0;
return root;
}
else
{
t = 0;
return root;
}
}
}

temp = 0; doesn't delete the leaf from the tree, just nulls a local variable.
You want to null some node's l or r in order to remove a node from the tree.
Try keeping the parent as well and once temp points to the leaf, nullify temp's parent r or l.
Same goes for t = 0; later on.
Note David's comment about first releasing this memory..
For example (assuming not deleting the root):
...
if(data < temp->data)
{
i=2*i;
parent = temp;
temp = temp->l;
}
else if(data > temp->data)
{
i = (2*i)+1;
parent = temp;
temp = temp->r ;
}
else
{
printf("%d\n",i);
break;
}
...
if(temp->l == 0 && temp->r == 0)
{
if (parent->l == temp)
parent->l = 0;
else
parent->r = 0;
// Free temp if needed
return root;
}
...
Also note that you have:
else if(temp->l == 0)
{
temp->data = temp->l->data;
Which is a dereference of a null pointer (temp->l is NULL), and the same thing for temp->r == 0 case.
Then you have
temp->l = 0;
but you're already in a temp->l == 0 case, so I don't think this is what you meant.

Related

Passed pointer becomes 0x1

I'm working on a school assignment and am stuck on this part. To summarize what the code is supposed to do, it is meant to put 100 random integers into a B-Tree and print out the sorted list of numbers. I get my random numbers easily enough and begin to insert them using the following function:
void BTree_Insert(BTREE* tree, int* dataInPtr) {
bool taller;
NODE* newPtr;
ENTRY upEntry;
if (tree->root == NULL) {
if (newPtr = (NODE*)malloc(sizeof(NODE))) {
newPtr->firstPtr = NULL;
newPtr->numEntries = 1;
newPtr->entries[0].dataPtr = dataInPtr;
newPtr->entries[0].rightPtr = NULL;
tree->root = newPtr;
(tree->count)++;
for (int i = 1; i < ORDER - 1; i++) {
newPtr->entries[i].dataPtr = NULL;
newPtr->entries[i].rightPtr = NULL;
}
return;
}
else {
printf("Overflow error 100 in BTree_Insert\a\n"), exit(100);
}
}
taller = _insert(tree, tree->root, dataInPtr, &upEntry);
if (taller) {
newPtr = (NODE*)malloc(sizeof(NODE));
if (newPtr) {
newPtr->entries[0] = upEntry;
newPtr->firstPtr = tree->root;
newPtr->numEntries = 1;
tree->root = newPtr;
}
else {
printf("Overflow error 101\a\n"), exit(100);
}
}
(tree->count)++;
return;
}
The first number enters fine (tree->root would be null at this point), but when the second number is inserted, it calls _insert, which is where my problems start. Here is the code for _insert:
bool _insert(BTREE* tree, NODE* root, int* dataInPtr, ENTRY* upEntry) {
if (root == 0x1) {
//printf("root is now 0x1");
}
int compResult;
int entryNdx;
bool taller;
NODE* subtreePtr;
if (!root) {
(*upEntry).dataPtr = dataInPtr;
(*upEntry).rightPtr = NULL;
return true;
}
entryNdx = _searchNode(tree, root, dataInPtr);
compResult = tree->compare(dataInPtr, root->entries[entryNdx].dataPtr);
if (entryNdx <= 0 && compResult < 0) {
subtreePtr = root->firstPtr;
}
else {
subtreePtr = root->entries[entryNdx].rightPtr;
}
taller = _insert(tree, subtreePtr, dataInPtr, upEntry);
if (taller) {
if (root->numEntries >= ORDER - 1) {
_splitNode(root, entryNdx, compResult, upEntry);
taller = true;
}
else {
if (compResult >= 0) {
_insertEntry(root, entryNdx + 1, *upEntry);
}
else {
_insertEntry(root, entryNdx, *upEntry);
}
(root->numEntries)++;
taller = false;
}
}
return taller;
}
When passing through root, it for some reason becomes 0x1 and I get a read access violation. I have verified that in BTree_Insert tree->root is not 0x1, so I really have no idea what's going on. Any insight as to how to fix this would be much appreciated.

Binary search tree delete not working, why?

I am trying to implement Binary search tree in C.
But I am stuck at the delete operation, when I run the code it doesn't delete the value specified.
Before calling delete:(calling inorder())
16 19 23
After calling delete:(calling inorder())
16 19 23
code:
void deleteNode(struct node *n, int data)
{
struct node *temp;
if(n->data==data)
{
if(n->left == NULL && n->right == NULL)
{
n=NULL;
}
else if(n->left == NULL && n->right!=NULL)
{
n->data = (n->right)->data;
n->right = NULL;
}
else if(n->left!=NULL && n->right == NULL)
{
n->data = (n->left)->data;
n->left=NULL;
}
else if(n->left != NULL && n->right != NULL)
{
temp = findMax(root);
n->data = temp->data;
temp = NULL;
}
}
else if(n->data > data)
{
deleteNode(n->left, data);
}
else if(n->data < data)
{
deleteNode(n->right, data);
}
}
I have other code which is working, but I want to know what is wrong with this code?
Edit:
I have edited the code with a few changes in it.
Now, When I try to delete the ROOT node.
I end up with this:
(inorder traversal)-> 16 23 23
Now,
Why is this happening when temp = NULL is making the maximum node NULL.
Note: I am not initializing temp as the code has been changed and it is initialized just before its use (temp = findMax(root)).
code inorder():
void inorder(struct node *root)
{
if(root!=NULL)
{
inorder(root->left);
printf("%d\n", root->data);
inorder(root->right);
}
}
Use this alternative code or use your temp tree in your method
struct node *temp = n; //then use temp tree in code
Alternative method
struct node *delete(struct node *tree, int data)
{
if(find(tree,data)==-1 || tree == NULL)
return tree;
if(tree->data == data)
{
if(tree->left==NULL && tree->right==NULL)
return NULL;
if(tree->right != NULL){
tree->data = min(tree->right);
tree->right = delete(tree->right,min(tree->right));
return tree;
}
tree->data = madata(tree->left);
tree->left = delete(tree->left,madata(tree->left));
return tree;
}
if(tree->data < data)
{
tree->right= delete(tree->right,data);
return tree;
}
tree->left= delete(tree->left,data);
return tree;
}
This is what worked for me,
struct node* deleteNode(struct node *n, int data)
{
struct node *temp;
temp = n;
if(n->data==data)
{
if(n->left == NULL && n->right == NULL)
{
n=NULL;
return NULL;
}
else if(n->left == NULL && n->right!=NULL)
{
n = n->right;
temp = NULL;
}
else if(n->left!=NULL && n->right == NULL)
{
n = n->left;
temp = NULL;
}
else if(n->left != NULL && n->right != NULL)
{
temp = findMax(root);
n->data = temp->data;
temp = NULL;
}
}
else if(n->data > data)
{
n->left = deleteNode(n->left, data);
}
else if(n->data < data)
{
n->right = deleteNode(n->right, data);
}
return n;
}

Big-O for using a for loop to insert into an AVL

I was writing a code sample for a company I applied for, and they asked that my code run in O(n) in the worst case. I decided to use an AVL tree, but to insert the values I was being given into the AVL tree I had to use a nested loop structure. Does that make my code run in O(n2) in the worst case or does it run in O(n log n)?
EDIT: here is a link to the code on my github: https://github.com/hsleiman1/Algorithms/blob/master/equilibriumIndexAVL.c
My code:
int equilibriumIndex(int A[], int N) {
int i, newRoot = 1;
while (newRoot < N) {
node *leftTree = NULL;
node *rightTree = NULL;
for (i = 0; i < N; i++) {
if (i == newRoot) continue;
if (i < newRoot) leftTree = insert(leftTree, A[i]);
if (i >= newRoot) rightTree = insert(rightTree, A[i]);
}
if (addSubTree(leftTree) == addSubTree(rightTree)) return newRoot;
free(leftTree);
free(rightTree);
newRoot++;
}
return 0;
}
int addSubTree(node *subTree) {
if (subTree == NULL)
return 0;
else
return (subTree->value * subTree->repeat) + addSubTree(subTree->left) + addSubTree(subTree->right);
}
node *leafInit(node *leaf, int key) {
leaf = (node*)malloc(sizeof(node));
if (leaf != NULL) {
leaf->value = key;
leaf->left = NULL;
leaf->right = NULL;
leaf->repeat = 1;
}
return leaf;
}
node *insert(node *leaf, int key) {
if (leaf == NULL)
leaf = leafInit(leaf, key);
else if (key < leaf->value)
leaf->left = insert(leaf->left, key);
else
if (key > leaf->value)
leaf->right = insert(leaf->right, key);
else
leaf->repeat++;
leaf = rotate(leaf, key);
return leaf;
}
node *rotate(node *subTree, int key) {
node *temp;
int balance = getBalance(subTree);
if (balance < -1) {
temp = subTree->left;
if (key > temp->value) {
subTree->left = rightRotate(subTree->left);
subTree = leftRotate(subTree);
}
} else
if (balance > 1) {
temp = subTree->right;
if (key < temp->value) {
subTree->right = leftRotate(subTree->right);
subTree = rightRotate(subTree);
}
} else
if (balance < -1 && key < subTree->value)
subTree = leftRotate(subTree);
else
if (balance > 1 && key > subTree->value)
subTree = rightRotate(subTree);
return subTree;
}
node *leftRotate(node *leaf) {
node *x = leaf->left;
node *y = x->right;
x->right = leaf;
leaf->left = y;
return x;
}
node *rightRotate(node *leaf) {
node *x = leaf->right;
node *y = x->left;
x->left = leaf;
leaf->right = y;
return x;
}
int height(node *leaf) {
if (leaf == NULL) return 0;
else return max(height(leaf->left), height(leaf->right)) + 1;
}
int max(int num, int num1) {
if (num < num1) return num1;
else return num;
}
int getBalance(node *leaf) {
return height(leaf->right) - height(leaf->left);
}
Using an AVL tree will never get you an O(n) complexity. If you do it right, which can be tricky, you will get O(n.log(n)), and if you miss, you may get a degenerate tree and a complexity of O(n2).
For an O(n) complexity, they are expecting you to use a hash table.

Bus error 10 in Radix Tree C program

I'm writing a program which does operations on a Radix trie and I'm stuck at add() function, getting the Bus error 10.
void addRec(struct tNode *p, char *w) {
int matches = prefixMatch(p->word,w);
bool insert = true;
if ((p == root) ||
((matches > 0) && (matches < strlen(w)) && (matches == strlen(p->word)))) {
char *updatedWord = &w[matches];
printf("%s\n", updatedWord);
struct tNode *tmp = p->child;
while (tmp != NULL) {
if (tmp->word[0] == updatedWord[0]) {
insert = false;
addRec(tmp, updatedWord);
}
tmp = tmp->brother;
}
if (insert) {
addChild(p,updatedWord);
}
} else if ((matches > 0) && (matches == strlen(w)) && (matches == strlen(p->word))) {
if (p->count < 0) p->count = ++globalCount;
else printf("ignored");
} else if ((matches > 0) && (matches < strlen(w)) && (matches < strlen(p->word))) {
struct tNode *tmp = malloc(sizeof(struct tNode));
tmp->word = &p->word[matches];
p->word[matches+1] = '\0';
tmp->child = p->child;
tmp->count = p->count;
tmp->brother = NULL;
p->child = tmp;
p->count = -1;
}
}
The error appears to be somewhere inside the while loop but I can't figure out where and what's wrong exactly. Please help.

my binary search tree program stopped working (C)

For some reason the insertion part of the code is not working as intended. When I run the program it just gives an error "bst.exe has stopped working" and it happens in this function. The whole idea of this portion of the code is to ITERATIVELY insert a new node and update the root.
static NODE *insert_i(NODE *r, int x)
{
NODE *leaf;
if(r == NULL)
{
leaf = malloc(sizeof(NODE));
leaf->left = NULL;
leaf->right = NULL;
leaf->val = x;
count++;
return leaf;
}
while(r)
{
if(r->val == x)
return r;
if(x < r->val && r->left != NULL)
r = r->left;
else if(x > r->val && r->right != NULL)
r = r->right;
}
leaf = malloc(sizeof(NODE));
leaf->left = NULL;
leaf->right = NULL;
leaf->val = x;
count++;
if(x < r->val)
r->left = leaf;
else
r->right = leaf;
return r;
}
void bst_insert(BST_PTR t, int x)
{
t->root = insert_i(t->root, x);
}
At this point, outside the loop
if(x < r->val)
r->left = leaf;
else
r->right = leaf;
r is NULL. So, if you access r->val, it will crash.
Try to keep track of the parent as shown below.
NODE *leaf;
NODE * par
while(r)
{
if(r->val == x)
return r;
par = r;
if(x < r->val && r->left != NULL)
r = r->left;
else if(x > r->val && r->right != NULL)
r = r->right;
}
leaf = malloc(sizeof(NODE));
leaf->left = NULL;
leaf->right = NULL;
leaf->val = x;
count++;
if(x < par->val)
par->left = leaf;
else
par->right = leaf;
return r;

Resources