Find and delete wrong node in a BST in C - c

I have a C problem which i need to check if a given Tree is a Binary Search Tree or not and then find which node is incorrect and delete it (from the problem definition, it will always be just one wrong node). For instance:
10
|
|
9 12
| |
| |
7 3 11 14
In this tree, element 3 is incorrect and should be deleted. In case of given tree is already a BST, algorithm should do nothing. I'm trying to adapt a solution from CodeForGeeks which verifies if a tree is a BST or not to instead returning a boolean, returning a pointer for the node which is wrong, but this isn't working well. Here's the method i came up with:
NODE* verifyBinaryTree(NODE* root, NO** previous){
if(node != NULL){
NODE* left= verifyBinaryTree(root->left, previous);
if(left != NULL){
return left;
}
if(*previous && root->data <= (*previous)->data) return root;
*previous = root;
return(verifyBinaryTree(root->right, previous));
}
return NULL;
}
I would enjoy if someone could help me to find the right logic behind this problem.

Here is an easy way to approach this problem . If you do inorder traversal on a valid BST , you will get the nodes sorted in increasing order .
You can do this inorder traversal and after storing them serially in a data structure (perhaps array) , check if the adjacent elements are not in increasing order . If you find such elements , you need to delete them .

Related

leetcode 110. Balanced Binary Treeļ¼ŒProblems with balanced tree code

I am working on LeetCode problem 110. Balanced Binary Tree:
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as:
a binary tree in which the left and right subtrees of every node differ in height by no more than 1.
I've seen solutions for this question, including this one:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int max(int a, int b){
return (a > b) ? a:b;
}
int height(struct TreeNode* root){
if(root == NULL) return 0;
return 1 + max(height(root->left),height(root->right));
}
bool isBalanced(struct TreeNode* root){
if(root == NULL) return 1;
int left = height(root->left);
int right = height(root->right);
return abs(left - right) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
My question is: why should this code be added?
isBalanced(root->left) && isBalanced(root->right);
It seems to be working fine when I delete this from the code. However, when the test case is [1,2,2,3,null,null,3,4,null,null,4], the code will return true, while the expected answer is false.
I am full of doubts about this test, because both ends of the test tree are the same depth, so abs(left-right) should be 0, and 0<=1, so shouldn't the answer for this test be true!?
the test case is [1,2,2,3,null,null,3,4,null,null,4],
So let's visualise that tree:
1
/ \
2 2
/ \
3 3
/ \
4 4
the code will return true, while the expected answer is false,
The expected answer is false: the above tree is not a balanced tree.
I am full of doubts about this test, because both ends of the test tree are the same depth, so abs(left-right) should be 0, and 0<=1, so shouldn't the answer for this test be true!?
You are right that abs(left-right) is 0 and that's within the bounds [-1,1], but in a balanced tree, this condition must be true in every node. So your code must also check that abs(left-right) is within the limits for other nodes. And then you can see that the first node with value 2, has a left-subtree that is 2 levels higher than its right-subtree (which is empty). So there we have a violation of the rule, and the correct answer is false.
This explains why you really need those two recursive calls to isBalanced.
a binary tree in which the left and right subtrees of every node differ in height by no more than 1.
Here you have already mentioned why your implementation is throwing up an error. Your code only checks the height balancing at the root node(topmost node).
The difference of heights in every node must be [-1,0,1] in a balanced tree. An easier visualization will be considering each node has a small tree itself.
Let this be the testcase [1,2,2,3,null,null,3,4,null,null,4].
1
/ \
2 2
/ \
3 3
/ \
4 4
If you only check the root node, the abs(left-right) is 0. But consider the left node 2. And visualize it a smaller tree or a subtree.
2
/
3
/
4
If this is a tree on its own then it's not balanced since abs(left-right) == 2.Since we have found a node that is not balanced we return false.
Thus to solve this problem, we have to consider each node as a separate tree itself. Such problems require recursive algorithms that checks the isBalanced property from the highest to the lowest nodes by calling their child nodes recursively.

Need help modifying a linked list in C

I have a linked list structure with values 6 5 4 3 in order. I need to subtract 1 from each term so that I have a new node with value 5 4 3 2. I don't know how you would do this because if I use a simple code such as.
while(node != NULL){
node->value = (node->value) -1;
node = node->next;
}
return node;
However this returns nothing because I'm essentially erasing any modifications I make. Any help would be greatly appreciated

Inserting an element in Binary Tree

Tried exploring a lot over the net, but could get any help,
Everywhere its like adding a node to the Binary Search tree.
Question: Requesting for algorithm and code snippet for adding a node to the Binary tree. ( or point me to correct URL )
Assumption:
As per my understanding, Binary Tree and Binary Search Tree is different? Correct me if I am wrong.
( request: if you are writing your code snippet please use proper variable name, that helps in understanding )
Eg: Binary Tree
5 7 3 x1 x2 x3
5
7 3
x1 x2 x3
Binary Search Tree 5 7 3 2 4 6
5
3 7
2 4 6
insert(int key, struct node **root)
{
if( NULL == *root )`
{
*root = (struct node*) malloc( sizeof( struct node ) );`
(*root)->data = key;
(*root)->left = NULL;
(*root)->right = NULL;
}
else if(key < (*root)->data)
{
insert( key, &(*root)->left );
}
else if(key > (*root)->data)
{
insert( key, &(*root)->right );
}
}
The difference between a Binary Tree and a Binary Search Tree is that though they both have restrictions that each node can have at most 2 child nodes, a Binary Search Tree (BST) also must have its left child be of equal or lesser value and the its right child must be of greater or equal value. This is why it is called a "Search" tree because everything is ordered numerically and it has an O(logn) run time for searching.
Because there isn't the requirement of being a BST, a Binary Tree can be stored in a vector (array). As you insert into the vector you build the Binary Tree in level-order fashion. The code is below:
// typedef the node struct to NODE
// nodeVector similar to STL's vector class
insert(int key, NODE** nodeVector)
{
NODE *newNode = (NODE*) malloc( sizeof( NODE ) );
newNode->data = key;
newNode->left = NULL;
newNode->right = NULL;
// add newNode to end of vector
int size = nodeVector->size();
nodeVector->push_back(newNode);
// if newNode is not root node
if(nodeVector->size() > 1)
{
// set parent's child values
Node* parent = (size/2)-1; // take advantage of integer division instead of using floor()
if (parent->left == NULL)
{
parent->left = newNode;
}
else
{
parent->right = newNode;
}
}
}
A Queue data structure can be used for inserting element in to a Binary Tree, since in Binary Tree the order of nodes is not maintained so we will insert the node as soon as we find any null.
Using Queue we will be traversing the Binary Tree in Level Order Traversal.
struct Treenode* temp;
Q = CreateQueue();
EnQueue(Q,root);
while(!IsEmptyQueue(Q))
{
temp = DeQueue(Q);
if(temp->left)
EnQueue(Q,temp->left);
else
{
temp->left=newNode;
DeleteQueue(Q);
return;
}
if(temp->right)
EnQueue(Q,temp->right);
else
{
temp->right=newNode;
DeleteQueue(Q);
return;
}
}
Since, I cannot comment I am writing this.
The above answer for binary tree insert function is wrong.
Suppose for 0, 1, 2 , 3, 4 , 5 passed in sequence to insert function,
its generating tree like
0
/
1
\
2
/
3
\
4
/
5`<br/>
of which inorder traversal will be 1 3 5 4 2 0
while answer should be
0
/ \
1 2
/ \ /
3 4 5
of which inorder traversal will be 3 1 4 0 5 2.
Since I also face the same problem, I came up with following solution over the net :-
You can use a queue to store the current node where we want to place the new node as we do in level order traversal and then we insert the nodes level by level.
Following link might help you :-
http://www.geeksforgeeks.org/linked-complete-binary-tree-its-creation/
I am posting this as answer because I dont have the necessary reputation to post a comment. Except for bagelboy all others have misunderstood the tree as either Binary Search Tree or Complete Binary Tree. The question is simple Binary Tree and Bagelboy's answer looks correct.

Printing in ascending order (sorting) from AVL trees

I need to define a main function that reads integers and prints them back in ascending order.
For example, if the input contains
12
4
19
6
the program should output
4
6
12
19
I need to use trees to do this however. I'm given the use of two functions insertavl, and deleteavlat my disposal. Their defintions are like so... http://ideone.com/8dwlU basically when deleteavl is called it deletes the node, and rebalances the tree accordingly
... If interested thier structures are in: http://ideone.com/QjlGe.
I've gotten this so far:
int main (void) {
int number;
struct node *t = NULL;
while (1 == scanf("%d",&number)) {
t = insertavl(t, number);
}
while (t != NULL){
printf("%d\n",t->data);
t = deleteavl(t, t->data);
}
}
But this doesn't print them in ascending order. Any suggestions would be helpful? thanks in advance!
Hint: in-order traversal on a BST is iterating the elements in ascending order.
Since an AVL Tree is a specific implementation of a BST, it also applies here.
EDIT: Explanation - why is this property of in-order traversal on a BST correct?
In in-order trvaersal, you access [print] each node after you accessed all the nodes in the left subtree. Since in a BST the root is bigger then all the nodes in the left subtree, it is what we wanted.
Also, in in-order traversal, you access each node before accessing all elements in the right sub-tree, and again, since it is a BST - this is exactly what we want.
(*)Note: This is not a formal proof, just an intuitive explanation why it is true.

convert Binary tree to Binary Search Tree inplace using C

Without using any extra space convert Binary Tree to Binary Search tree.I came up with the following algo but It doesn't work.
BTtoBST(node *root)
1.if the root is NULL return
2.else current=root
3.if (current->left > current) swap(current->left , current)
4.if (current->right < current) swap(current->right , current)
5.current=current->left
6 go to 3 if current!=NULL else go to 4
7.current=current->right
Thanks in advance
PS:I saw this link but was not of much help!!
Convert Binary Tree -> BST (maintaining original tree shape)
You can swap the nodes including subtrees (not only the node content) like in an AVL Tree http://en.wikipedia.org/wiki/AVL_tree
Just keep swapping as long as BST constraints are violated, restarting deep first search from root after each swap.
Perform a post-order (bottom up) traversal of the tree, taking the nodes that are visited and inserting them into a BST.
Does "without any extra space" preclude recursion?
If not, then something like:
# top level call passes null for bst
bt_to_bst (root, bst)
# nothing to add to bst; just return it
if null(root) -> return bst
# if this is a leaf node, stick it into the BST
if null(root->left) && null(root->right)
return bst_insert(bst, root)
# otherwise add all of left subtree into the bst and then the right tree
bst = bt_to_bst (root->left, bst);
return bt_to_bst (root->right, bst);
bt_to_bst is a filtering operation; it takes an existing bst and returns a new one with the given node added to it.
Adding a leaf node to the bst is safe because we will never visit it again, so we can overwrite its left and right pointers.

Resources