Can a single Node<E> direct to LinkedList? - list

I'm currently working on building a general tree with pre-order structure. However, since my tree can have multiple children, I need to make a list that contains nodes and make that inner node directing to the next list.
I'm wondering if I can build that kind of structure on Java
If I can. Can I direct a single node to the DoublyLinkedList structure in code?
Here is my Node class in the Tree class (code fraction)
class Tree<E> {
//single node structure
private static class Node <E> {
private E e;
private Node<E> parentNode;
private LinkedNode<E> childList;
public Node(E e, Node<E> p, LinkedNode<E> n) {
this.e = e;
this.parentNode = p;
this.childList = n;
}
}
//list structure to store nodes
private static class LinkedNode<E> { //<- problem1
private Node<E> parentNode;
private Node<E> nextSibling;
}
private E root;
private int size = 0;
}
The problem with my code is at LinkedNode part I have to make the object type as Node not just E otherwise it will not contain a node info. So, is there any way to make this done?

class Tree<E> {
//root of the tree
private Node root;
//single node structure
private static class Node <E> {
//Store data of the node
private E e;
//store the child in an ArrayList
//Each child will be represented by Class Node itself
private ArrayList< Node<E> > childList;
}
private int size = 0;
}
What I perceive, is you're trying to implement a generic tree. Here's how I would've done it.
Cheers!

Related

Creating a class with attributes of this class type + inheritance to other class (Node classs and NodeAVL)

I'm trying to do the following code:
class Node
{
protected:
int *value;
Node *leftChild;
Node *rightChild;
friend class BST;
public:
Node(int value = 0);
virtual ~Node();
virtual int info();
};
Node::Node(int value) : leftChild(nullptr), rightChild(nullptr) {
this->value = new int(value);
std::cout << "Creating the node " << *(this->value) << "\n";
}
class NodeAVL : public Node
{
private:
friend class AVL;
public:
int *balanceFactor;
NodeAVL(int value = 0);
virtual ~NodeAVL();
};
NodeAVL::NodeAVL(int value) : Node(value) {
this->balanceFactor = new int(0);
std::cout << "Creating the AVL node " << *(this->value) << " with balance factor " << *(this->balanceFactor) << "\n";
}
Now, my problem is that I should derive NodeAVL (mandatory), and I have a problem with the Node class (base class), because there are declarations of Node *leftChild and Node *rightChild, and when I create an AVL node, it creates its children of type Node*. How can I create it with the type NodeAVL*?
Or how can I create a class T like:
class T{
T* leftChild;
T* rightChild;
}
so that I would have Node class have Node children and NodeAVL which is derived from Node have NodeAVL children?
Since you have tagged your post with polymorphism I will give you a runtime polymorphism based answer. You don't.
Part of the point of runtime polymorphism is that an object dervied from the base class can be passed and stored as an object of the base class while still retaining its overriden functionality (Yes slicing is an issue but we are dealing with pointers here). Therefore you do not need Node to be changed to NodeAVL, simply setting leftChild or rightChild to point at an object of NodeAVL instead of Node is enough, any overriden methods will call the method in NodeAVL.
You are setting your nodes to nullptr anyway but if you didn't then you could make a Node contructor which takes pointers for leftChild and rightChild (possibly make it protected so only derived classes can use it).
As a side note use your initaliser list to set value instead of setting it afterwards. Also prefer smart pointers to naked pointers.

Constructing AST during LR parsing

I have written an LR(1) parser that can successfully parse strings in the language of my grammar into a Concrete Syntax Tree, but I am now trying to construct an Abstract Syntax Tree.
I am using an inheritance design for my AST nodes:
struct ASTNode {
virtual Type typeCheck() = 0;
}
struct IDNode : public ASTNode {
string name;
...
}
struct INTNode : public ASTNode {
int value;
...
}
struct BOPNode : public ASTNode {
ASTNode *pLeft;
ASTNode *pRight;
...
}
struct Add_BOPNode : public BOPNode {
...
}
struct ParamNode : public ASTNode {
string name;
ASTNode *pTypeSpecifier;
...
}
struct ParamListNode : public ASTNode {
vector<ParamNode*> params;
...
}
struct FuncDec : public ASTNode {
string functionName;
ASTNode *pFunctionBody;
ASTNode *pReturnType;
ASTNode *pParams;
...
}
When I perform a reduction in my LR(1) parser I generate a new node depending on the rule that was used for the reduction. This is pretty straightforward for most of the nodes, but I'm not sure of a clean way to implement a node that contains a list of other nodes.
Using the ParamListNode from above as an example:
struct stack_item {
int state;
int token;
string data;
ASTNode *node;
};
/// rule = the number of the rule being reduced on
/// rhs = the items on the right-hand side of the rule
ASTNode* makeNode(int rule, vector<stack_item> rhs) {
switch(rule) {
/// <expr> ::= <expr> '+' <term>
case 1: return new Add_BOPNode(rhs[0].node, rhs[2].node);
/// <param> ::= IDENT(data) ':' <type>
case 2: return new ParamNode(rhs[0].data, rhs[2].node);
/// <param_list> ::= <param>
case 3: return new ParamList(rhs[0].node);
/// <param_list> ::= <param_list> ',' <param>
case 4: {
auto list = dynamic_cast<ParamListNode*>(rhs[0].node);
list->params.push_back(rhs[2].node);
return list;
}
...
}
}
Since generating a node requires a subclass of ASTNode to be returned, I have to create a subclass that encloses a vector<> with each sub-node. However, since not every node needs to be a list structure, I have to dynamic_cast<> to the subclass before I can access the internal list.
I feel like there should be a cleaner way to handle a list of sub-nodes without having to rely on dynamic_cast<>.
Another question is about the FuncDec node. It has pParams which should be a ParamList (or vector<Param*> directly), but to do that I would have to dynamic_cast<> the incoming ASTNode to a ParamList or Param node. Again, I feel like there should be a way to not use dynamic_cast<>, but I can’t think of one.
Also, if you have any other suggestions about how I can better structure or implement anything that would be greatly appreciated :)
My LRSTAR Parser Generator creates an abstract-syntax tree (AST) by using only one class, Node. Each node is the same structure, a pointer to the token (in the symbol table if a leaf node), and pointers to parent, child and next nodes. The next pointer allows you to have a list of nodes (multiple children for a parent node). This has worked well for many years.
During processing of the AST, it is the function associated with the node which takes care of the processing of the node. For example, the add function will do something different than the subtract function. The functions are different, instead of having a different class for each type
of node.
Here is the node structure that I use:
class Node
{
public:
int id; // Node id number
int prod; // Production (rule) number
int sti; // Symbol-table index (perm or temp var).
int prev; // Previous node.
int next; // Next node.
int line; // Line number.
int child; // Child node.
int parent; // Parent node.
};

Inheritance and AVL/BST Trees

Is there any way to use the same insert function for both Bst and Avl tree? The problem is that Bst and Avl have different Node types, but I don't want to make the Bst Node a general case(with height and Node* parent inside, which makes no sense because there is no need of parent and height inside a Bst).
class Bst
{
public:
struct Node
{
int value;
Node* left;
Node* right;
};
Node* insert(Node* node) {/* do stuff using Bst::Node */}
// ...
};
class Avl : public Bst
{
public:
struct Node : public Bst::Node
{
int height;
Node* parent;
};
// now I want that Bst::insert use this Node
// instead of the old one
Node* insert(Node* node)
{
Node* inserted_node = Bst::insert(node);
/* rotations stuff */
return inserted_node;
}
};
Roughly what I'm trying to do is make Bst::Node "virtual".
So, how can I solve the problem of implenting the Avl Tree without rewriting the entire insert function just because Node changed?
Actually I'm also working on this stuff and I think you're very clear to describe what you want.
At the first, it's may be little confuse about the given interface, insert() should not return the pointer of the Node, doesn't it. We may use the findNode() function, which return the pointer of the Node and exactly do this work only.
Back to the main question, may be you can use the template to set your Node type for every function in the BST.
But the BST is not just a abstract interface, which also implement the BST operation, so it's not CRTP..
The pseudo code for now may be the following :
// pre-define :
//parent ptr also alleviate the implementation of BST.
template<typename T>
class BST{
... omit..
protected:
template<typename node_type>
class BST_Node{
public:
T val;
BST_Node *left, *right, *parent;
BST_Node():left{nullptr},
right{nullptr},
parent{nullptr}, val{}{};
// empty {} default to value initialization.
}
... omit ...
}
template<typename T>
class AVL_Node : public BST_Node{
public:
short height;
AVL_Node(T val):BST_Node(val), height(0){};
}
template<typename T>
void insert(T val){
AVL_Node<T> Node(val);
BST<T>::insert_node<AVL_Node>(Node);
AVL_Node<T>* ptr = BST<T>::find_node<AVL_Node>(val);
ptr->height = BST<T>::get_height(ptr);
state = chk_balance(ptr);
switch(state){
case 0: // tree very balance..
break;
case 1:
LL_rotate(ptr);
break;
case 2:
RR_rotate(ptr);
break;
... omit
}
}
# help this post solve your question..
Maybe you want CRTP (in which case you haven't given enough info about your needs for even a rough example, but a simpler less powerful template approach may make more sense to you. Have a base class (under each of your tree types) that has no data members, and just defines static template functions for the common code. Since the functions are static, you need to pass in the relevant data (for insert that should be &root) but that should not be much trouble. (Rough and untested):
struct tree_base
{
template <class Node>
static Node* insert( Node** where, Node* what)
{
Node* here;
while ( (here = *where) != 0 )
{
if ( *what < *here ) where = &(here->left);
else if ( *here < *what ) where = &(here->right);
else
{
Trying to insert something already there, what should be done
}
}
*where = what;
return what; // Is that the desired return?
}
};
Then each of your real tree classes would inherit from tree_base and would call tree_base::insert(&root, new_node) to do the common parts of insert
A CRTP version of that would allow root to be a member of the base class even though it points to the Node type of the derived class. Given root as a member of the base class, the insert function doesn't need to be static and doesn't need to take &root as input. And since a CRTP base class is already correctly templated to have access to the Node type, the base class insert method wouldn't need to be a template. All that would be a lot more things to learn (by looking at some real examples of CRTP) and probably overkill for the code sharing you want.

Would making a binary search tree out of a struct over a class node be bad?

I'm not sure if i should.. or should not use a struct to create a binary search tree, the other option is to create the nodes out of a separate node class. with a data, left and right. Which one is better? And why?
heres my code for the BST
template <typename T>
class BST : public SearchableADT<T>
{
public:
BST(void){ head = NULL; numnodes = 0; }
virtual ~BST(void);
virtual int loadFromFile(string filename);
virtual void clear(void);
virtual void insertEntry(T info);
virtual void deleteEntry(T info);
virtual bool isThere(T info);
virtual int numEntries(void);
//needed for comparison to AVL
int BST<T>::height(t_node* tPTR);
protected:
struct t_node
{
string data;
t_node *L;
t_node *R;
};
int numnodes;
t_node* head;
t_node* cPTR; //current pointer
t_node* pPTR; //parent pointer
t_node* tPTR; //temporary pointer
}; // end of class BST
I'm not sure if you understand the difference between struct and class but basically:
struct
Has public access for all of its members by default and
class
Has private access for all of its members by default.
You can achieve the same thing with both of them but many programmers, including myself, tend to use structs for POD objects (Plain Old Data) for straight up access (It makes it easier to write less).
That said, I think you should put your Node class outside in a different file since the BST and Node classes are very different. Since you gave your BST class a template, I am assuming that you are gonna use more than just the Node class, which gives more reason to separate the files for the projects that you might not use the Node class. If you aren't going to use more than just a Node class, you might consider removing the template and defining the Node struct/class inside the BST class!
It is better to create two classes, one for the BST and another for the node. They are two different abstractions. A node is a simpler abstraction whose main purpose is to hold the data necessary to define a BST. A BST is a higher level abstraction. It's a collection class with its own constraints and expectations.

Super vs Subclass inheritance of a constructor C++

So this is the base class for a binary search tree with left, right, parent and data.
template<class Data>
class BSTNode
{
public:
/** Constructor. Initialize a BSTNode with the given Data item,
* no parent, and no children.
*/
BSTNode(const Data & d) : data(d)
{
left = right = parent = 0;
}
BSTNode<Data>* left;
BSTNode<Data>* right;
BSTNode<Data>* parent;
Data const data; // the const Data in this node.
/** Return the successor of this BSTNode in a BST, or 0 if none.
** PRECONDITION: this BSTNode is a node in a BST.
** POSTCONDITION: the BST is unchanged.
** RETURNS: the BSTNode that is the successor of this BSTNode,
** or 0 if there is none.
*/
BSTNode<Data>* successor()
{
BSTNode<Data>* cursor;
BSTNode<Data>* par;
cursor = this->right;
par = this->parent;
if (this->right != NULL)
{
while (cursor->left != NULL) {
cursor = cursor->left;
}
return cursor;
}
if ((this->right == NULL) && (this == par->left))
return this->parent;
if ((this->right == NULL) && (this == par->right))
{
do
{
cursor = par;
par = par->parent;
if (par == NULL)
{return cursor;}
} while(cursor != par->left);
return par;
}
if (this->right == NULL && this->parent == NULL)
return NULL;
return NULL;
}
};
The subclass is RSTNode that is supposed to use all the members of BSTNode and add a priority on top of that:
template<class Data>
class RSTNode: public BSTNode<Data>
{
public:
int priority;
RSTNode(Data const & d)
: BSTNode<Data>(d)
{
//call a random number generator to generate a random priority
priority = rand();
}
};
Now the problem is i'm not sure how to implement the constructor for the RSTNode as it does not recognize the members of BSTNode for some reason. I know that it should recognize them as it is supposed to inherit this information. Any help is appriciated.
Ok, I compiled this in Visual Studio...
template<class Data>
class BSTNode
{
public:
/** Constructor. Initialize a BSTNode with the given Data item,
* no parent, and no children.
*/
BSTNode(const Data & d) : data(d)
{
left = right = parent = 0;
}
BSTNode<Data>* left;
BSTNode<Data>* right;
BSTNode<Data>* parent;
Data const data; // the const Data in this node.
};
template<class Data>
class RSTNode : public BSTNode<Data>
{
public:
int priority;
RSTNode(Data const & d)
: priority(rand()),
BSTNode<Data>(d)
{
left = 0; //Accessible because public
right = 0;
parent = 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
RSTNode<std::string> node(std::string("test"));
return 0;
}
It compiled so no access issues. Like other posters above it seems to me that you are either not posting the detail of your problem, or you are not understanding something fundemental.
>Now the problem is i'm not sure how to implement the constructor for the RSTNode as it >does not recognize the members of BSTNode for some reason. I know that it should recognize >them as it is supposed to inherit this information. Any help is appriciated.
The code above implements a constructor, or if you wanted to specifically have left, right and parent set then you would need :
BSTNode(const Data & d, BSTNode* l, BSTNode* r, BSTNode* p)
: data(d),
left(l),
right(r),
parent(p)
{
}
and then use it in the RSTNode, or have a similar one for RSTNode that passed through to that one....
RSTNode(Data const & d, BSTNode* l, BSTNode* r, BSTNode* p)
: priority(rand()),
BSTNode<Data>(d,l,r,p)
{
}
Hope that helps a little, note that you should prefer initialiser lists to direct access to members in the ctor. But if you cannot change the base class then you would need to...
Corrected typo - data -> Data
That's because the default scope for data members is private. You need to declare them as protected if you want to access them in a subclass.
Better still, add a constructor to BSTNode that allows you to pass in initialisation values, and call this from the RSTNode constructor, since it should be the base class that is managing the lifetime of its members.
If I've read this correctly your attempting to inherit from a templated class:
class RSTNode: public BSTNode<Data>
Where your class definition of BSTNode isn't a templated class?
class BSTNode {
Is this part of the problem or have you pasted the wrong code?
You could fix it by either templating BSTNode
template <typename T> class BSTNode {
or deriving RSTNode from non-templated BSTNode:
class RSTNode: public BSTNode
However the fact that you've tried to to what you've written implies you aren't really understanding class definitions at a much deeper level, and the fact you are trying to set base class parameters directly in a derived class constructor and that you've made them public would lead me to believe you need to learn more about object oriented design - so although this might solve your problem technically, it's only tip of the iceberg when it comes to the issues you are having.
Also saying "it does not recognize the members of BSTNode for some reason" isn't very helpful as I suspect that isn't the exact output of your compiler when you try to do it.