Cascading or inheriting attributes from multiple node declarations in graphviz - graphviz

I'm using graphviz/dot to generate a graph.
I want to group nodes and/or edges in the graph into semantic classes, with each class having a set of node and/or edge properties that cascade or inherit similar to CSS. However, if I group a single node into multiple classes, the later attribute declaration will override the earlier attribute declaration, even if that attribute was not specified in the later declaration. In particular, it reverts the value to the default/higher-scoped value.
For example:
node [shape="hexagon", style="filled", fillcolor="lightskyblue1"];
{ node [shape="box"]; a; b; }
{ node [fillcolor="red"]; b; c; }
What I want:
a [shape="box", style="filled", fillcolor="lightskyblue1"];
b [shape="box", style="filled", fillcolor="red"];
c [shape="hexagon", style="filled", fillcolor="red"];
What I get:
a [shape="box", style="filled", fillcolor="lightskyblue1"];
b [shape="hexagon", style="filled", fillcolor="red"];
c [shape="hexagon", style="filled", fillcolor="red"];
Is this possible?

Different result here.
a [shape="box", style="filled", fillcolor="lightskyblue1"];
b [shape="box", style="filled", fillcolor="lightskyblue1"];
c [shape="hexagon", style="filled", fillcolor="red"];
This looks correct for me. Objects inherit the default attributes on definition (=first occurrence). b is defined on the line with [shape="box"]. There fillcolor="lightskyblue1" is in effect from outer scope.
from http://www.graphviz.org/content/dot-language (highlighting by me):
If a default attribute is defined using a node, edge, or graph statement, or by an attribute assignment not attached to a node or edge, any object of the appropriate type defined afterwards will inherit this attribute value.
graphviz version 2.38.0

Related

How to extend a binary tree node without using an interface?

type struct Node {
x Data
l *Node
r *Node
}
Given the struct above, I am working on various implementations of binary search trees, all within the same package so that they can share internals without a public interface. However, some trees require a rank field as part of their node, which I would like to create as an extension of the base struct. I do not want the trees that do not require a rank field to allocate a node with a rank field.
type struct RankedNode {
Node
z rank
}
At first, this seems correct and communicates clear intent to me. However, this does not work because the internal l and r fields are of type Node, breaking code like this:
func (p *RankedNode) heapify() *RankedNode {
// ...
p.l.heapify()
p.r.heapify()
}
Of course, p.l and p.r are of type Node, so heapify is not defined. We can make the assumption that any node can only be linked to nodes of the exact same type.
Q: Is a Node interface and type assertions the only way to achieve this without generics?
func (p *RankedNode) heapify() *RankedNode {
// ...
p.L().(*RankedNode).heapify()
p.R().(*RankedNode).heapify() // :(
}

Creating and visualizing a Linked List

I'm still new to coding and I'm trying to learn how to create a linked list. What does this part mean? I can't seem to visualize this in my head.
static class Node {
int data;
Node next;
Node(int d){
data = d;
next = null;}
}
So this is a simple visual of a linked list. Your code represents a node class, so thats just the framework for a node. But you can think of that code representing one node, so it could represent the fourth node in this diagram. Thus, its data value would be {D} and its next value would be null.
In a linked list, the next node object it represented by the next variable. So if the node you are looking at is the second node, then your next variable will be the third node.

How to create a new edge using existing nodelabel/headlabel in graphviz/dotEditor without duplicating a new one

digraph G {
"DUT0" [label="DUT0"]; "DUT1" [label="DUT1"];
"DUT0" -> "DUT1" [headlabel="1", taillabel="2"];
"DUT1" -> "DUT1" [taillabel="1", headlabel="3"];
}
I am using the below script in graphviz dotEditor to create my graph.
The script mentioned above creates below diagram.
My requirement is: Instead of creating a new taillabel(1) on node DUT1(Edge from 1-->3) , it should use the same existing one.
How can I achieve this? Please help, Thanks in advance.
Adding the resulting image which is required.
Probably not possible, but maybe you should have a look at the node placements (based on wind directions, as you also indicate in your hand drawing) and leave one of the labels like:
digraph G {
"DUT0" -> "DUT1" [headlabel="1", taillabel="2"];
"DUT1":n -> "DUT1" [ headlabel="3"];
}
The result:

How To Copy A Full Non-Binary Tree Including Loops

Please share me your thoughts and any solution to this problem of copying the full non-binary tree, and it may include loops as well in which some of the children are connected to other parent nodes.
Example:
Here, "A" is the root or parent, and its children are "B" and "C" as usual, and at the end, child "G" is connected back to its grand-parent level "B", and similarly the "I" is connected to its immediate parent "C", so these are like a loops, and this also needs to be copied in the new tree as is. So, here we need additional logic to identify the loops while copying the children nodes, and not getting into an infinite loop, and eventually return the copy of the whole tree.
A
- B
- D
- E
- F
- G --> B
- C
- I --> C
- K
This class or node structure can be like this:
public class Node{
private String value;
private List<Node> childrens;
public Node copyTree(Node root) {
...
//return
}
}
Thanks for our help.
I think the most direct way of doing this is to keep a map from nodes that have been copied to their copies. Then just check against the map before making a new copy of a node. Something like this (untested) should work:
public static Node copyTree(Node root) {
return copyTree(root, new HashMap<>());
}
private static Node copyTree(Node root, Map<Node, Node> images) {
Node copy = images.get(root);
if (copy == null) {
copy = new Node();
// register the copy before recursing on children
images.put(root, copy);
// now fill in the copy
copy.value = root.value;
copy.children = new ArrayList<>();
for (Node child : root.children) {
copy.children.add(copyTree(child, images);
}
}
return copy;
}

Is there any way to delete any node in Binary Tree without having root node refrence?

I was trying for this problem but not able to crack it. We have a Binary Tree and I want delete a given node from the tree but we don't have reference of root node. I am getting an idea how can we do this without having reference of root node. We do have the reference to node5, like in the image.
Update considering the new edit.
Since this is NOT a Binary Search Tree, in this case I'm assuming the node order in the tree is not relevant and the tree will not have duplicates, so removing node5 will be possible with the same data structure we defined above, but we need to include a parent node reference (for step 3 detailed below):
node {
d: data
leftChild: node
rightChild: node
parent: node
}
Now we can remove node5 modifying the tree without accessing/modifying the root (node1).
You'll have to do the following:
(Remember that node 5 is also a Binary subtree, so after
modifying it, we want the whole Binary Tree to still remain one!)
Find node5's deepest node. You need to traverse node5's node reference as a tree.
(*Be careful with how you pass the arguments. root should be a copy,
so that it doesn't mess with node5' as a root, but level and
deepestNode should be references.)
findDeepestNode(root: node, level: integer, deepestNode: node) {
if (root != null) {
level = level + 1
find(root.left, level)
if (level > deepestlevel) {
deepestNode = root; // node reference to the deepestNode
deepestlevel = level;
}
find(root.right, level);
}
}
Once executing this, deepestNode in your case will be node7 or node8. It doesn't matter.
Now make node5's value equal to deepestNode's value. In our pseudocode:
node5.data = deepestNode.data // Replacing node5's value with the deletingNode's one.
The tree now has a duplicate value. You still have deepestNode. So now you assign deepestNode parent's reference to null and delete
deepestNode as a reference. This step is the reason we need to include a parent node reference.
Your removal is complete!
Given nothing else but the tree itself, then you'll always have to search for the node you want to remove before removing it. If you can set yourself up for success by keeping pointers to the nodes you may want to remove beforehand, then the answer could be yes!

Resources