In the following code, I'm trying to get a better hand at understanding how recursion actually work. I've always been a bit confused about it's actual working. I want to know what value does the inorder() function actually return in every step. From where does it get these values of 0,0,11,0,0,11,12,0,0,11 respectively. Could someone tell me the logic? It's a basic inorder tree traversal program.The reason why I'm trying to understand these outputs is because the same logic is somehow used to find the depth of the tree( I think) where with every recursion the value of depth increases without initialization.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
};
struct node* newNode(int data)
{
struct node* node=(struct node*)malloc(sizeof(struct node));
node->data=data;
node->left=NULL;
node->right=NULL;
return node;
}
int inorder(struct node *temp) {
if (temp != NULL) {
printf("\nleft %d\n",inorder(temp->left));
printf("\n%d\n", temp->data);
printf("\nright %d\n",inorder(temp->right));
}
}
int main()
{
struct node *root=newNode(1);
root->left=newNode(2);
root->right=newNode(3);
root->left->left=newNode(4);
root->left->right=newNode(5);
inorder(root);
getchar();
return 0;
}
This function should be changed to the following (the first and last print in the original code will only get you more confused!):
int inorder(struct node *temp) {
if (temp != NULL) {
inorder(temp->left);
printf("%d\n", temp->data);
inorder(temp->right);
}
}
The recursion starts with the left branch of a specific node (usually the "root") - printing recursively (in-order) all the nodes on that left-branch, then printing the current node, moving on to printing recursively (in-order) all the nodes in the right branch.
By the way, if you want to keep that tree "ordered" (meaning, all the nodes on the left branch are smaller than the node, and all the nodes on the right branch are bigger or equal to the node) you should change:
root->left->left=newNode(4);
root->left->right=newNode(5);
to:
root->right->right=newNode(4);
root->right->right->right=newNode(5);
Related
I cannot get this tree to act correctly. i keep getting exit error codes. What is going on with the tree and how would i use the search function in main? it seems the methods are coded correctly but i am not using it correctly in main. i keep geting exit errors that are not 0 and none of the methods i try to use in the main function work. now i am just typing to fill in space because apparently my post is mostly code and not enough text!
//Binary Tree Practice
#include <iostream>
struct node{
int data;
node* right;
node* left;
};
class bTree{
public:
bTree(){
root=NULL;
}
~bTree(){
destroyTree();
}
void addNode(int key);
node *search(int key);
void destroyTree();
private:
node* root;
void addNode(int key,node*nod);
node *search(int key, node *leaf);
void destroyTree(node*&node);
};
node *bTree::search(int key)
{
return search(key, root);
}
void bTree::destroyTree()
{
destroyTree(root);
}
void bTree::addNode(int key)
{
if(root!=NULL)
addNode(key, root);
else
{
root=new node;
root->data=key;
root->left=NULL;
root->right=NULL;
}
}
void bTree::addNode(int key, node* nod) {//ADD a node in correct position.
if (key < nod->left->data) {
if (nod->left != NULL)
addNode(key, nod->left);//RECURSION traverse tree to the left until
find a NULL node
else {//When NULL node is found
nod->left = new node;
nod->left->data = key;
nod->left->left = NULL;
nod->right = NULL;
std::cout<<"node added"<<std::endl;
}
} else if (key > nod->right->data) {
if (nod->right != NULL)
addNode(key, nod->right);//RECURSIONTraverse right till find a null
node
else {//NULL node found
nod->right = new node;//Create new node
nod->right->data = key;//set NODE data to KEY
nod->right->right = NULL;
nod->left = NULL;
}
}
}
node *bTree::search(int key, node *leaf)
{
if(leaf!=NULL)
{
if(key==leaf->data)
return leaf;
if(key<leaf->data)
return search(key, leaf);
else
return search(key, leaf->right);
}
else return NULL;
}
void bTree:: destroyTree(node*&node){
if(node==NULL){
destroyTree(node->left);
destroyTree(node->right);
delete node;
}
}
int main() {
bTree *trees=new bTree();
trees->addNode(10);
trees->addNode(6);
trees->addNode(14);
node *check;
}
The first thing your addNode function with signature void bTree::addNode(int key, node* nod) does is this:
if (key < nod->left->data) {
The problem with your code is that nod->left will lead to a crash, since the left node has not been initialized and leads to an unauthorized memory access, or what is called a segmentation fault. Let's go through the main loop.
addNode(10) - The addNode function with signature void bTree::addNode(int key) is called, root is null, so root is created with left and right nodes set to NULL.
addNode(6) - The addNode function with signature void bTree::addNode(int key) is called, root is NOT null, so addNode with signature void bTree::addNode(int key, node* nod) is called. Then nod->left, and crash.
This is a common problem in low level programming, and my advice to you is to put debug prints inside the functions to see which parameters entered, and where exactly the code crashed. If you can pinpoint the exact line that leads to the crash (in thise case the line with nod->left) you can solve these kinds of problems more easily in the future.
In order to fix your issue, simply make sure to initialize the left and right nodes before you access them.
I'm attempting to use a struct to manage accessing nodes on a tree. Whenever I access the method of the parent's child node, the parent reference on the subsequent call gets lost (i.e. parent.child.method(child) -> [parent becomes nil]-> parent(the previous child).child ... etc).
Here is the error snippet from my file.
type Node struct {
Left *Node
Right *Node
value int
}
func (parent *Node) determineSide(child *Node) (Node, Node) {
if child.Value < parent.Value {
if parent.hasLeftNode() {
return parent.Left.determineSide(child)
}
return parent.addLeftNode(child)
} else if child.Value > parent.Value {
if parent.hasRightNode() {
return parent.Right.determineSide(child)
}
return parent.addRightNode(child)
}
return *child, *parent
}
I attempted to solve this by trying to find a way to inform the method that the new reference should be parent.Left. Things like using *parent.Left and &parent.Left didn't seem to be correct.
A solution may might be to move this code outside of the struct and have another function handle the outcome for a quick fix, but I'd like to understand why this isn't working out of the box. Thought process here is influenced by using this.child.determineSide(child).
Full code is here.
Edit
Here is some output from the terminal that might give even further context. Looks like I'm having a check type issue leading to the problem.
parent &{<nil> <nil> 2}
parent.Left <nil>
parent.LeftNode true
child &{<nil> <nil> 1}
parent <nil>
child &{<nil> <nil> 1}
Okay, I know what u'r exactly asking finally.
New() methods returns a value, not a pointer, which means u can't see later change in caller. What the caller got is only a value copy of the Node. So the parent what u print will always be {Left:<nil> Right:<nil> Value:2}.
So the same with addLeftNode() and addRightNode().
Just use pointer, not value to achieve your goal.
See pointers_vs_values
I think it's just the Visit() method where the problem is.
It will never visit right child when u immediately return after visited left child.
The left and right child are not mutually exclusive, so the second if-clause should not use else if, which would be if.
The visiting order also has problem.
Before:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
fmt.Println("Node value:", parent.Value)
if parent.hasLeftNode() {
return parent.Left.Visit()
} else if parent.hasRightNode() {
return parent.Right.Visit()
}
return *parent, parent.Value
}
Modified:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
if parent.hasLeftNode() {
parent.Left.Visit()
}
fmt.Println("Node value:", parent.Value)
if parent.hasRightNode() {
parent.Right.Visit()
}
return *parent, parent.Value
}
Additionally, as to me, Visit() shouldn't return any values.
Problem originated from incorrect type checking. The function successfully handled the call, but the method I was using wasn't accurate in confirming whether a node was assigned.
// isNode checks whether the provided property is a Node.
func (parent *Node) isNode(property interface{}, typeset interface{}) bool {
fmt.Println(reflect.TypeOf(property) == reflect.TypeOf(typeset))
// this always referred to the address for the base Node struct or similar falsy.
return reflect.TypeOf(property) == reflect.TypeOf(typeset)
}
// hasLeftSide tests whether the Parent Node has a Node assigned to its left side.
func (parent *Node) hasLeftNode() bool {
return parent.Left != nil //parent.isNode(parent.Left, (*Node)(nil))
}
// hasRightSide tests whether the Parent Node has a Node assigned to its right side.
func (parent *Node) hasRightNode() bool {
return parent.Right != nil // parent.isNode(parent.Right, (*Node)(nil))
}
Below is my code. I'm trying to return head node back after I insert value to either left or right node. I understood the concept of insertion, but I'm unable to understand how can I return my head node back to that now it is back to original state with addition node added.
Here is exactly I don't understand.
When I insert my node how can I break the loop and return its head node back.
Recursion is stack concept which will output based on LIFO and if it is lifo how can I have head node returned back
Here's my code:
class Node {
int data;
Node left;
Node right;
}
static Node Insert(Node root,int value)
{
return nodeHelper(root,value);
}
static Node nodeHelper(Node root,int value){
Node nodeTracker = root;
Node temp;
if(root!=null){
if(value>root.data){
if(root.right==null){
temp =new Node();
temp.data = value;
root.right = temp;
return nodeTracker;
}
else{
nodeHelper(root.right,value);
}
}
else{
if(root.left==null){
temp=new Node();
temp.data = value;
root.left = temp;
return nodeTracker;
}
else{
nodeHelper(root.left,value);
}
}
}
else{
temp=new Node();
temp.data = value;
return temp;
}
}
}
To return the root of the tree, you need a third parameter that you pass around to keep track of the root. Like this:
Node* nodeHelper(Node* nodeTracker, Node* parent, int value)
Remove the local nodeTracker variable.
Your recursive calls become:
return nodeHelper(nodeTracker, parent.left, value);
(and, of course, same thing for the right branch)
And your initial call in the insert function is:
return nodeHelper(root, root, value);
Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.
Trying to wrap my head around how to correct my code. I have the idea up, but I get stuck during the implementation.
when I step through the code below, I can reconstruct part of the BST from a pre-order traversal. But at some point, I will have function call like:
recon(preOrd,2,2)
which results in a leaf not being assigned. I do yet know how to correct this.
I have seen other threads on this topic, but want to iron out my issue so I can really learn this concept of rebuilding the BST.
public static Node recon(int[] preOrd,int start,int end){
if (start==end){
return null;
}
Node root = new Node (preOrd[start]);
int div=start;
for (i=start+1;i<=end && preOrd[i]<preOrd[start];i++){
div=i;
}
Node left= reconstruct(preOrd,start+1,div);
Node right= reconstruct(preOrd,div+1,end);
root.setLeft= left;
root.setRight=right;
return root;
}
Turns out this is pretty straightforward. Just needed to correct my thinking on the updating of leaf nodes..
public static Node recon(int[] preOrd,int start,int end){
Node root = new Node (preOrd[start]);//declare the new node
if (start>end){ //this is illegal, so return null
return null;
}
if (start==end){
return root;
}
int div=start;
for (int i=start+1;i<=end preOrd[i]<preOrd[start];i++){
div=i;
}
Node left= reconstruct(preOrd,start+1,div);
Node right= reconstruct(preOrd,div+1,end);
root.setLeft= left;
root.setRight=right;
return root;
}