-2

I'm trying to make a simple program to learn about Binary Tree Traversals in C++. However, when I try to compile my program with make I get the following error:

Undefined symbols for architecture x86_64:
  "Node::postOrderTraversalNode(Node*)", referenced from:
      BinaryTree::postOrderTraversal(BinaryTree*) in BinaryTree.o
      postOrderTraversalNode(Node*) in Node.o
ld: symbol(s) not found for architecture x86_64

I have looked at other StackExchange posts and have narrowed it down to something having to do with how I set up my makefile but I still can't seem find the error. Any help would be greatly appreciated.

Makefile:

BinaryTree_Program: Main.o BinaryTree.o Node.o
    clang++ BinaryTree.o Node.o Main.o -o BinaryTree_Program

Main.o: Main.cpp
    clang++ -c Main.cpp -o Main.o

BinaryTree.o: BinaryTree.h BinaryTree.cpp
    clang++ -c BinaryTree.cpp -o BinaryTree.o

Node.o: Node.h Node.cpp
    clang++ -c Node.cpp -o Node.o

clean:
    rm BinaryTree_Program Main.o BinaryTree.o Node.o

Main.cpp

#include "BinaryTree.h"
#include "Node.h"

int main() {
  Node* root = new Node(10);
  Node* nd1 = new Node(5);
  Node* nd2 = new Node(3);
  Node* nd3 = new Node(2);
  Node* nd4 = new Node(15);
  Node* nd5 = new Node(12);
  Node* nd6 = new Node(20);

  root->left = nd1;
  root->right = nd4;

  nd1->left = nd2;
  nd1->right = nd3;

  nd4->left = nd5;
  nd4->right = nd6;

  //       10
  //      /  \
  //    5    15
  //   / \   / \
  //  3  2  12 20

  BinaryTree* tree = new BinaryTree(root);
  BinaryTree::inOrderTraversal(tree);
}

BinaryTree.cpp

#include "BinaryTree.h"
#include "Node.h"

// The in, pre, and post is based on where we visit the root

BinaryTree::BinaryTree(Node* nd) {
  root = nd;
}

// The in, pre, and post is based on where we visit the root
void BinaryTree::inOrderTraversal(BinaryTree* t) {
  if (t != NULL){
    Node::inOrderTraversalNode(t->root);
  }
}

void BinaryTree::preOrderTraversal(BinaryTree* t) {
  if (t != NULL) {
    Node::preOrderTraversalNode(t->root);
  }
}

void BinaryTree::postOrderTraversal(BinaryTree* t) {
  if (t != NULL) {
    Node::postOrderTraversalNode(t->root);
  }
}

Node.cpp

#include "Node.h"

Node::Node(int d) {
  data = d;
  left = NULL;
  right = NULL;
}

void Node::visitNode(Node* nd) {
  std::cout << nd -> data << " " << std::endl;
}

void Node::inOrderTraversalNode(Node* nd) {
  if (nd != NULL) {
    Node::inOrderTraversalNode(nd -> left);
    Node::visitNode(nd);
    Node::inOrderTraversalNode(nd -> right);
  }
}

void Node::preOrderTraversalNode(Node* nd) {
  if (nd != NULL) {
    Node::visitNode(nd);
    Node::preOrderTraversalNode(nd -> left);
    Node::preOrderTraversalNode(nd -> right);
  }
}

void postOrderTraversalNode(Node* nd) {
  if (nd != NULL){
    Node::postOrderTraversalNode(nd -> left);
    Node::postOrderTraversalNode(nd -> right);
    Node::visitNode(nd);
  }
}

Node.h

#ifndef NODE_H
#define NODE_H
#include <iostream>

class Node {
public:
  // member data
  int data;
  Node* left;
  Node* right;

  // constructor
  Node(int d);

  // member functions
  static void inOrderTraversalNode(Node* nd);
  static void preOrderTraversalNode(Node* nd);
  static void postOrderTraversalNode(Node* nd);
  //static void levelOrderTralversalNode(Node* n);
  static void visitNode(Node*);
};

#endif

BinaryTree.h

#ifndef BINARYTREE_H
#define BINARYTREE_H

#include <iostream>
#include "Node.h"
using namespace std;

class BinaryTree {
public:
  // member data
  Node* root;

  // constructor
  BinaryTree(Node* n);

  // member functions
  static void inOrderTraversal(BinaryTree* t);
  static void preOrderTraversal(BinaryTree* t);
  static void postOrderTraversal(BinaryTree* t);
  //void levelOrderTraveral(BinaryTree* t);
};

#endif
Tomislav
  • 131
  • 6
  • 1
    If the linker can't find the symbol, and you think you've defined the symbol, check where you think you've defined it see what sort of typo you've made. I've sometimes had to stare at things three times before finding my typing mistake, although yours should be easy to spot. – 1201ProgramAlarm May 06 '19 at 01:57
  • 1
    Show us Node.h - that's got to be where it is wrong. – Jerry Jeremiah May 06 '19 at 02:00
  • @1201ProgramAlarm fantastic I’ll give this a shot thanks – Tomislav May 06 '19 at 02:17
  • @JerryJeremiah hey I edited! How do you figure it’s in Node.h? – Tomislav May 06 '19 at 02:18
  • It looks like you have a `postOrderTraversalNode(Node*)` defined, but no `Node::postOrderTraversal(Node*)`, even though the latter function is what you have declared in Node.h (and what's being called from other functions). So the issue is just a little typo in Node.cpp. (Seeing Node.h lets us see the discrepancies between the declarations presented there and the definitions presented in Node.cpp) – hegel5000 May 06 '19 at 03:10
  • The last function in your Node.cpp is a free function and is NOT a class member like all the others. You need to prefix the name of the last function in Node.cpp with `Node::` to make it a member. – Jerry Jeremiah May 06 '19 at 03:22

1 Answers1

1

Node.h declares the following functions:

static void inOrderTraversalNode(Node* nd);
static void preOrderTraversalNode(Node* nd);
static void postOrderTraversalNode(Node* nd);
static void visitNode(Node*);

Node.cpp contains the declaration for Node::inOrderTraversalNode and Node::preOrderTraversalNode as well as this free function:

void postOrderTraversalNode(Node* nd) {
  if (nd != NULL){
    Node::postOrderTraversalNode(nd -> left);
    Node::postOrderTraversalNode(nd -> right);
    Node::visitNode(nd);
  }
}

But does not contain a declaration for Node::postOrderTraversalNode

It is clear that the free function postOrderTraversalNode was meant to be a member function so it should be declared as a class member like the others:

void Node::postOrderTraversalNode(Node* nd) {
  if (nd != NULL){
    Node::postOrderTraversalNode(nd -> left);
    Node::postOrderTraversalNode(nd -> right);
    Node::visitNode(nd);
  }
}
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32