So, I'm taking data structures and algorithms and I'm trying to answer the following question:
(20 marks) Exercise 6.7. Create a subclass of BinaryTree whose nodes have fields for storing preorder, post-order, and in-order numbers. Write methods preOrderNumber(), inOrderNumber(), and postOrderNumbers() that assign these numbers correctly. These methods should each run in O(n) time.
Now... I'm confused about what the question is even asking. Are they asking me to store an array in each Node that records the preOrder, inOrder and postOrder values of the whole tree??? Or are they asking me to create a subclass of Node that contains an integer that's hold the Next value, according to a preOrder, inOrder or postOrder value, relative to the Node we're in...
So, I went with the former and assumed that they wanted the array. But the trouble now is that I've created a new version of Node and I'm trying to call this preOrderNumber() function at the bottom but I get the following error:
BTNode.h contains the code I used in a previous question to construct a binary tree. It just defines a class Node with a left, right, and parent pointer, as well as an add() function to add new values to the tree, and a preOrderNEXT() function that gets the next value in the tree according to that transversal order. the same is true for inOrderNEXT(), and postOrderNEXT()
#include <iostream>
#include "BTNode.h"
#include <vector>
using namespace std;
class BinaryTree : public Node {
public:
vector<int> preOrderNumbers;
vector<int> inOrderNumbers;
vector<int> postOrderNumbers;
BinaryTree(int x);
~BinaryTree();
int preOrderNumber();
int inOrderNumber();
int postOrderNumber();
};
BinaryTree::BinaryTree(int x) : Node(x) {}
BinaryTree::~BinaryTree() {}
int BinaryTree::preOrderNumber() {
Node* next_Node = preOrderNEXT(this);
while (next_Node != NULL) {
preOrderNumbers.push_back(next_Node->data);
next_Node = preOrderNEXT(next_Node);
}
}
int BinaryTree::inOrderNumber() {
Node* next_Node = inOrderNEXT(this);
while (next_Node != NULL) {
inOrderNumbers.push_back(next_Node->data);
next_Node = inOrderNEXT(next_Node);
}
}
int BinaryTree::postOrderNumber() {
Node* next_Node = postOrderNEXT(this);
while (next_Node != NULL) {
postOrderNumbers.push_back(next_Node->data);
next_Node = postOrderNEXT(next_Node);
}
}
int main() {
Node* BinaryT = new BinaryTree(rand() % 1000);
int arr[] = { 71, 6, 28, 49, 41, 42, 88, 72, 21, 84, 85, 94, 59, 29, 2, 97, 33, 23, 78 };
cout << "We add these integers, one by one, using a for loop to the binary tree:\n" << endl;
cout << "[ 60, ";
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
BinaryT->add(arr[i]);
cout << arr[i] << ", ";
}
int x = BinaryT->preOrderNumber();
}
OKAY, So yea I think I found out the real crux of this question and I'll answer this here for anyone else stuck in this situation.
The key to making sense out of this question is to visit its location in the textbook. The course coordinator ripped this question out of the textbook and doesn't provide any context. In Pat Morin's book Open Data Structure, An Introduction, on page 149 there's an illustration 6.10.
So, what this question IS ACTUALLY ASKING you to do is write a subclass for the Binary Tree Nodes such that each Node holds an integer that keeps track of its position within the corresponding traversal type. So maybe your Node would be visited 3rd in preOrder, 4th in an inOrder, and 2nd in a postOrder traversal. So that Node should hold a 3, a 4, and a 2 in the corresponding position. And then you need a function to update that position in O(n) time.
Related
I'm doing a coding challange on LeetCode and I'm asked to traverse each level and at the end return a nested vectors with values node values for each values.
So if I have a tree like:
Which is
Input: root = [1,null,3,2,4,null,5,6]
And expected output is
Output: [[1],[3,2,4],[5,6]]
The definition for the Node is as follows:
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
I'm attempting an iterative solution that is as follows:
class Solution {
public:
vector<vector<int>> answer;
stack<Node*> nodes;
vector<vector<int>> levelOrder(Node* root) {
if(root == NULL)
return answer;
nodes.push(root);
answer.push_back(vector<int>() = {root->val});
while(!nodes.empty())
{
Node* curr = nodes.top();
nodes.pop();
vector<int>temp;
for(int i = 0; i < curr->children.size(); i++)
{
nodes.push(curr->children[i]);
temp.push_back(curr->children[i]->val);
}
if(temp.size() != 0)
answer.push_back(temp);
}
return answer;
}
};
However it consistently fails 20th test case where the input is:
[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
The expectation is:
[[1],[2,3,4,5],[6,7,8,9,10],[11,12,13],[14]]
My output is
[[1],[2,3,4,5],[9,10],[13],[8],[12],[6,7],[11],[14]]
I'm having trouble visualising and drawing this N-ary tree on paper, so I have a hard time comprehending where my algorithm went wrong.
The problem with your code is that for each node you visit, you append all its children as a new list to the answer list. Your code does not group children on the same level but with different parents into one list, as would be expected by the solution.
Let us step through your code to see what happens:
Before the loop, you push the root node onto the stack and push a singleton set with the root node value to the answer:
stack = {1}
answer = { {1} }
The first iteration pops the 1 from the stack. You then iterate over the children 2,3,4,5, which are pushed on the stack. Afterwards, the list of children is pushed to the answer list.
stack = {2,3,4,5}
answer = { {1}, {2,3,4,5} }
The next iteration pops the 5 from the stack. You then iterate over the children 9, 10. They are pushed onto the stack. Afterwards, the list of children is pushed to the answer list.
stack = {2,3,4,9,10}
answer = { {1}, {2,3,4,5}, {9, 10} }
The next iteration pops the 10 from the stack. It has no children, so nothing happens.
stack = {2,3,4,9}
answer = { {1}, {2,3,4,5}, {9, 10} }
The next iteration pops the 9 from the stack. You then iterate over the single child 13, which is pushed to the stack. A singleton list containing 13 is pushed to the answer set.
stack = {2,3,4}
answer = { {1}, {2,3,4,5}, {9, 10}, {13} }
The next iteration pops the 4 from the stack. You then iterate over the single child 8, which is pushed to the stack. A singleton list containing 8 is pushed to the answer set.
stack = {2,3,8}
answer = { {1}, {2,3,4,5}, {9, 10}, {13}, {8} }
Your can see that your answer list is wrong from here. The 8 is on the same level as 9 and 10, so it should have been added to the {9,10} sub-list in the answer list, instead of creating a new list {8}. This should be sufficient to illustrate the problem, so I will not step through the code further.
To ensure that nodes on the same level are grouped into the same sub-list in the answer list, we have to keep track of the current level when visiting each node. We can do this by extending the stack to hold pairs of the current node and its depth. Each node value at depth d will then be appended to the dth sub-list in the answer list. This ensures that nodes on the same level are grouped into one sub-list.
std::vector<std::vector<int>> get_vals_per_level(const Node *root) {
std::vector<std::vector<int>> vals_per_level{};
std::stack<std::pair<const Node *, int>> stack{};
stack.emplace(root, 0);
while (!stack.empty()) {
auto [current, depth]{stack.top()};
stack.pop();
if (vals_per_level.size() == depth) {
vals_per_level.emplace_back();
}
// Append node value to the answer list for the current depth
vals_per_level[depth].push_back(current->val);
auto& children{current->children};
for (auto it{children.rbegin()}; it != children.rend(); it++) {
stack.emplace(*it, depth + 1);
}
}
return vals_per_level;
}
The code uses structured bindings from C++17.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm working on a C++ program that is supposed to utilize a linked list to create a hypercard stack (whatever that is). The problem is, I have no idea what I'm doing. I've written some code, but it crashes, and honestly I have no idea if it even meets the specifications for what I need it to do if it did work as written. Here's the code I've come up with.
Update
Also, as some of you have mentioned, I'd like to use the std::list library if that would make this easier, but I have no idea how to do so, any help would be greatly appreciated.
This is my .h file:
//program6.h
#include <iostream>
#include <fstream>
#include <list>
using namespace std;
class Node {
public:
Node();
Node(char code, int num, string data);
Node(Node & node);
~Node();
bool readFile();
void setNext(Node* next);
void print();
private:
char Code;
int Num;
string Data;
Node *Next;
};
My Implementation File:
//program6.cpp
#include "program6.h"
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Node {
public:
Node();
Node(char code, int num, string data);
Node(Node & node);
~Node();
bool readFile();
void setNext(Node* next);
void print();
private:
char Code;
int Num;
string Data;
Node *Next;
};
Node::Node() {
Code = '\0';
Num = 0;
Data = "";
Next = NULL;
}
Node::Node(char code, int num, string data) {
char Code = code;
int Num = num;
string Data = data;
Next = NULL;
}
Node::Node(Node & node) {
Code = node.Code;
Num = node.Num;
Data = node.Data;
Next = NULL;
}
Node::~Node() {
}
bool Node::readFile() {
char code = '\0';
int num = 0;
string data = "";
ifstream inputFile;
inputFile.open("prog6.dat");
if(!inputFile) {
cerr << "Open Faiulre" << endl;
exit(1);
return false;
}
Node *head = NULL;
while(!inputFile.eof()) {
inputFile >> code >> num >> data;
Node *temp = new Node(code, num, data);
temp->setNext(head);
head = temp;
}
inputFile.close();
head->print();
return true;
}
void Node::setNext(Node* next) {
Next = next;
}
void Node::print() {
cout << Code << " " << Num << " " << Data;
if(Next != NULL)
Next->print();
}
And my main/test file:
//program6test.cpp
#include "program6.h"
#include <iostream>
#include <fstream>
#include <list>
using namespace std;
int main() {
Node list;
if(list.readFile())
cout << "Success" << endl;
else
cout << "Failure" << endl;
return 0;
}
And here is the output I get when I compile and run this program:
[cs331129#cs ~]$ g++ -o prog6 program6test.cpp
[cs331129#cs ~]$ prog6
terminate called after throwing an instance of 'St9bad_alloc'
what(): St9bad_alloc
Aborted
And here are the "directions" I was given:
The hypercard “stack” concept is more general than a stack since “cards”
(elements) can be inserted anywhere and the entire “stack” can be traversed back
to the “home card”. Using circular lists, implement a hypercard stack.
Suppose we have a class or record structure (below) that contains a key code
(integer), a string of information (type Entry) 25 characters or fewer and a pointer
typedef struct elem_tag {
Key key;
Entry fact;
struct elem_tag * link;
} Node_type;
We can create a “hypercard stack”, read in information from a file, build a linked list of cards, and perform operations (insert(i), delete(d), traverse(t), home(h), forward(f), print(p)) on the list. For example, given a data file containing:
i 27 Mary had a little lamb
i 15 Today is a good day
i 35 Now is the time!
i 9 This lab is easy and fun
p
we produce a “hypercard stack” below.
-------Tail/Current
v
---> 27 ---> 15 ---> 35 ---> 9 ---
| Mary... Today... Now... This... |
----------------------------------------------------------------------------
Note that 27 is the “home card” (the home card is the next one after the one tail points to) and the card printed will be associate with “Current” (i.e., “This lab ...”). If we now process the following data file items:
d 35
t
i 37 Better now.
we will have the following list (note that traverse (t) should output each “fact” encountered for the entire list from the current pointer).
--- Current ---- Tail
v v
---> 27 ---> 15 ---> 37 ---> 9 ---
| Mary... Today... Better... This... |
-------------------------------------------------------------------------------
If we process the data item
h
the list will be
--- Current --- Tail
v v
---> 27 ---> 15 ---> 37 ---> 9 ---
} Mary... Today... Better... This... |
-------------------------------------------------------------------------------
To delete 9 (i.e., d 9 appears in the data file) the card before must be found (“Current points to it”) and “Tail” adjusted.
Write a C++ program to do the following:
Read in the information and build a “hypercard” linked list
Process all codes and data. Check the code first before attempting to read
any additional data. Remember to check for special cases (i.e., list is empty, list has one element, etc.).
Input:
Each input data line in the file will consist of a character code and the appropriate data (no errors will be introduced) and will be in prog6.dat. Read and process each line separately to the end of the file.
Output:
Output will consist of facts (strings) from print (p) or traverse (t) commands and an active response for each command.
Hints:
Declare a list type, either as a class or a record (struct is a public class) - for example:
typedef struct list_tag{
Node_type * current;
Node_type * tail;
} List_type;
Build the initial linked list by inserting each data item in turn at the end of the list. Maintain “Tail” and “Current” pointers. You must check to see if the “
Tail” pointer is NULL before insertion, otherwise insertion is AFTER the “Current” position. Deletion will cause the “Current” pointer to be set to point at the card before the one being deleted (unless it is the last card in which case “Tail” and “Current” must become NULL). Forward (f) should move the “Current” pointer to the next card.
Write a separate function for each ADT list operation (i.e., init/create, insert, delete, print, traverse, home), developed first as stubs, then as full functions. Use the standard technique of placing the main, functions, and headers in separate files
Here is the file I'll be using for the input:
i 27 Mary had a little lamb
i 15 Today is a good day
i 35 Now is the time!
i 9 This lab is easy and fun
p
d 35
t
i 37 Better Now.
f
p
h
p
d 27
d 15
d 37
d 9
i 44 This should be it!
t
p
I have no idea where to go from here or how to do anything else. I've been reading tutorials all night, but it's just not clicking as to how to apply anything I'm reading it this program. I'm just trying to make it through this class with a C seeing as I've already changed my major for next semester since I suck at all of this. Can anyone help?
The problem is, I have no idea what I'm doing
Hint:
I'm working on a C++ program that is supposed to utilize a linked list
to create a hypercard stack (whatever that is).
There is no any sense to declare two times class Node: one as a stand alone class and other as an internal class of class List. Also some functions also have no sense. For example member function
bool readFile():
creates a local list
Node *head = NULL;
while(!inputFile.eof()) {
inputFile >> code >> num >> data;
Node *temp = new Node(code, num, data);
temp->setNext(head);
head = temp;
}
that results in a memory leak.
It would be better to define a list that has internal structure Node.
Take into account that there is standard single linked liststd::forward_list in C++
I am trying to build my own implementation of a Binary Search Tree. I have pretty much everything working, I wanted to write a recursive method that prints the values in the tree in order. I used the following:
void innerPrint(Node * node) {
if (node->getLeft() != NULL) innerPrint(node->getLeft());
cout << node->getValue() << " ";
if (node->getRight() != NULL) innerPrint(node->getRight());
}
This is a private function, then the actual print function just calls this with my RootNode as the initial input. Below is my output. My question is, what causes this percent sign to appear? I've had a similar problem in the past, where everything that needs to be printed is done, but also this % appears at the end.
but I can't figure out why this is sometimes printed to the screen.
EDIT:
class BinarySearchTree {
private:
// Inner class Node, node contains a comprable value and pointers to other Node
class Node {
private:
int value;
Node * left = NULL;
Node * right = NULL;
Node * parent = NULL;
public:
// Getter, setter methods for Node
};
Node * root; // This is the top node of the tree
public:
BinarySearchTree (int value) {
root = new Node(value);
}
};
what #dabhaid said. this is most surely your prompt getting printed on the same line because your output does not end with \n. this is my zsh, with the verbiage in prompt edited out:
crap > printf "hey\n"
hey
crap > printf "hey"
hey%
crap >
I am in the process of implementing a Binary Search tree that gets represented using the Array implementation. This is my code so far: Take note that I have done with the Structure of tree and it is being saved as a Linked List. I want to convert this linked list into an array.
My thoughts on how to go about this are as followed. Make a return_array function. Have the Size of the array set to the Max number of nodes( 2^(n-1)+1) and go through the linked list. Root node would be # position 0 on the array then his L-child = (2*[index_of_parent]+1) and R-child = (2*[index_of_parent]+2). I looked around for a bit and searched to find something that can get me an idea of how I can keep track of each node and how I can go through each one.
Am I overthinking this problem?
Can there be a Recursion?
Also, I'm considering creating a visual tree instead of an array but have no idea how to space it out correctly. If anyone has an idea on how to do that it would be awesome to get a better understanding of that.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
struct node {
int data;
struct node* left;
struct node* right;
};
void inorder(struct node* node){
if(node){
inorder(node->left);
cout << node->data << " ";
inorder(node->right);
}
}
void insert(struct node** node, int key){
if(*node == NULL){
(*node) = (struct node*)malloc(sizeof(struct node));
(*node)->data = key;
(*node)->left = NULL;
(*node)->right = NULL;
printf("inserted node with data %d\n", (*node)->data);
}
else if ((*node)->data > key){
insert((&(*node)->left),key);
}
else
insert((&(*node)->right),key);
}
int max_tree(struct node* node){
int left,right;
if(node == NULL)
return 0;
else
{
left=max_tree(node->left);
right=max_tree(node->right);
if(left>right)
return left+1;
else
return right+1;
}
}
//This is where i dont know how to keep the parent/children the array.
void return_array(struct node* node, int height){
int max;
height = height - 1;
max = pow(2, height) - 1;
int arr [height];
}
int main(){
int h;
struct node* root = NULL;
insert(&root, 10);
insert(&root, 20);
insert(&root, 5);
insert(&root, 2);
inorder(root);
cout << endl;
cout << "Height is: ";
cout << max_tree(root);
h = max_tree(root)
return_array(root, h)
}
Considering that you want to efficiently store a binary search tree, using
l = 2i + 1
r = 2i + 2
will waste space every time your tree encounters a leaf node that is not occurring at the end of the tree (breadth-first). Consider the following simple example:
2
/ \
1 4
/ \
3 5
This (when transformed breadth-first into an array) results in
[ 2, 1, 4, -, -, 3, 5 ]
And wastes two slots in the array.
Now if you want to store the same tree in an array without wasting space, just transform it into an array depth-first:
[ 2 1 4 3 5 ]
To recover the original tree from this, follow these steps for each node:
Choose the first node as root
For each node (including root), choose
a) the left child as the next smaller key from the array after the current key
b) the right child as the next bigger key from the array, being no larger than the smallest parent key encountered when last branching left, and smaller than the direct parent's key when you are currently in it's left branch
Obviously finding the correct b) is slightly more complex, but not too much. Refer to my code example here.
If I'm not mistaken, transforming to and from an array will take O(n) in either case. And as no space is wasted, space complexity is also O(n).
This works because binary search trees have more structure than ordinary binary trees; here, I'm just using the binary search tree property of the left child being smaller, and the right child being larger than the current node's key.
EDIT:
After doing some further research on the topic, I found that reconstructing the tree in preorder traversal order is much simpler. The recursive function doing that is implemented here and here, respectively.
It basically consists of these steps:
As long as the input array has unseen entries,
If the value to insert is greater than the current branch's minimum value and less than the current branch's maximum allowed,
Add a node to the tree at the current position and set it's value to the current input value
Remove current value from input
If there are items left in the input,
Recurse into the left child
Recurse into the right child
The current minimum and maximum values are defined by the position inside the tree (left child: less than parent, right child: greater than parent).
For more elaborate details, please refer to my source code links.
If you want to store the tree node in a array,you had better to start from 1 position of your array!So the relation between the parent and its children should be simple:
parent = n;
left = 2n;
right = 2n + 1;
you should BFS the tree,and store the node in the array(If the node is null you should also store in the array using a flag ex 0),you should get the very array of the tree!
To do this you have to follow these steps.
Create an empty queue.
Make the first node of the list as root, and enqueue it to the queue.
Until we reach the end of the list, do the following.
a. Dequeue one node from the queue. This is the current parent.
b. Traverse two nodes in the list, add them as children of the current parent.
c. Enqueue the two nodes into the queue.
Time Complexity: Time complexity of the above solution is O(n) where n is the number of nodes.
I'm trying to write a program to do an inverse search of telephone numbers (user gives a number and program prints out the corresponding person + other numbers that belong to it). Now I have saved the persons' datas in a linked list and am trying to bild up a tree.
Each tree element will save a pointer to a person's data, an index (which is corresponding to a part of the telephone number, for example if the number starts with '0' the index of the root's first child node is '0') and a vector of pointers to it's children.
What I can do so far is saving the first given number in the Tree but there seem to be problems when trying to save more than one number in the tree. Maybe the problem is with the pointers to the children nodes, but i'm not sure there. Here's the said part of the code:
class Tree {
public:
Datensatz *data; //data stored in node
char number; //index of node - part of a telephone number
Tree* wurzel; //root
vector<Tree*> nextEls; //vector of children of node
Tree(int zahl);
/*
div. functions
*/
void add(vector<char>); //called to add telephone number to tree
};
void Tree::hinzufRek(vector<char> telNum)
{
Tree *aktEl = new Tree(); //latest node
aktEl=this->wurzel; //starts with root
int check = 0;
for (int i=0; i<telNum(); i++) {
char h = telNum(i);
if(aktEl->nextEls.size()!=0){
int j;
for (j = 0; j<aktEl->nextEls.size(); j++) {
if (h == aktEl->nextEls[j]->number) { //if latest number already exists in node children...
aktEl = aktEl->nextEls[j];
check = 1;
break;
}
}
if (check == 0) {
aktEl->nextEls.push_back(new Tree(h));
aktEl = aktEl->nextEls[j];
}
}
else { //if there are no current children to latest node
aktEl->nextEls.push_back(new Tree(h));
aktEl = aktEl->nextEls[0];
}
}
}
}
Furthermore, I thought it would be a good idea to delete the Tree* aktEl object at the end of the function, but that only leads to really strange results. I'm not sure if the above code is very clear or if it can be easily understood, but I hope one of you can help me...
Maybe I'm just overseeing something...
Thank you in advance!
roboneko42