See below binary tree.
And see implementation of this algo here: http://msdn.microsoft.com/en-us/library/ms379572(v=vs.80).aspx
1 level 0
2 3 level 1
4 5 6 7 level 2
8 9 10 11 12 13 14 15 level 3
My question is: How do I discover subtree from this tree based on the level? Lets say I want to discover two leveled subtree from 15 numbered node. Then result should be
3
6 7
12 13 14 15
If I search 3 leveled tree then it should be returned me above described full tree from 1 to 15.
Give me suggest for any code or algorithm or function which should be resolve this problem?
Assuming a Node class defined as:
public class Node
{
public Node Left { get; set; }
public Node Right { get; set; }
public int Value { get; set; }
public Node(int value)
{
Value = value;
}
}
You can add the following two methods to this class to achieve what you're trying to do:
public Node GetSubtree(int value, int depth)
{
int foundDepth;
return GetSubtreeHelper(value, depth, out foundDepth);
}
private Node GetSubtreeHelper(int value, int depth, out int foundDepth)
{
if (Value == value)
{
foundDepth = 0;
return depth == foundDepth ? this : null;
}
if (Left != null)
{
var node = Left.GetSubtreeHelper(value, depth, out foundDepth);
if (foundDepth != -1)
{
return ++foundDepth == depth ? this : node;
}
}
if (Right != null)
{
var node = Right.GetSubtreeHelper(value, depth, out foundDepth);
if (foundDepth != -1)
{
return ++foundDepth == depth ? this : node;
}
}
foundDepth = -1;
return null;
}
Testing this using the tree in your question:
GetSubtree(15, 0) = Node 15
GetSubtree(15, 1) = Node 7
GetSubtree(15, 2) = Node 3
GetSubtree(15, 3) = Node 1
GetSubtree(15, 4) = null
Related
Trying to swap the second and third nodes from a doubly linked list in c# with the following method:-
public static void swapNodes(List dblLinkList)
{
Node tempnodeTwo = dblLinkList.firstNode.next; //node two in list
Node tempnodeThree = dblLinkList.firstNode.next.next; //node three in list
Node tempnodeFive = tempnodeTwo.previous;
Node tempnodeSix = tempnodeThree.next;
tempnodeThree.previous = tempnodeFive;
tempnodeThree.next = tempnodeThree;
tempnodeTwo.previous = tempnodeTwo;
tempnodeTwo.next = tempnodeSix;
}
The following shows the output: The first is the original list and the second is the result of the method.
N:19:16 19:16:9 16:9:15 9:15:15 15:15:N
N:19:16 16:16:15 9:15:15 15:15:N
Where am I going wrong?? I have already studied previous questions about this topic which gave me the idea for the code but now stuck!
It seems that you assume tempnodeThree is the third and tempnodeTwo is the second node
of the linked list regardless of the changes you make but this is not the case.
After the initializations what you get is:
tempnodeFive <--> tempnodeTwo <--> tempnodeThree <--> tempnodeSix
And you need is:
tempnodeFive <--> tempnodeThree <--> tempnodeTwo <--> tempnodeSix
So what you have to change from left to right are:
tempNodeFive.next, tempNodeTwo.previous, tempNodeTwo.next, tempNodeThree.previous, tempNodeThree.next, tempNodeSix.previous
Let's go over them following the 2nd linked list representation:
tempNodeFive.next = tempNodeThree;
tempNodeTwo.previous = tempnodeThree;
tempNodeTwo.next = tempnodeSix;
tempNodeThree.previous = tempnodeFive;
tempNodeThree.next = tempnodeTwo;
tempNodeSix.previous = tempnodeTwo;
These six lines are what you need.
PS: You can reconsider variable names for a readable and maintainable code, esp. tempNodeFive and tempnodeSix because five and six does not make any sense as an index and it arises confusion while reading the code.
well here in these lines
tempnodeThree.next = tempnodeThree;
tempnodeTwo.previous = tempnodeTwo;
you are setting the next of a node to itself and the previous of another to itself.
don't you mean
tempnodeThree.next = tempnodeTwo;
tempnodeTwo.previous = tempnodeThree;
I think you would have an easier time if you used better names.
I also would not implement this function like this -- I'd make the function suit it's name like this:
public static void swapNodes(Node a, Node b)
{
if (a == null) return;
if (b == null) return;
Node afterA = a.next;
Node beforeA = a.previous;
a.previous = b.previous;
if (b.previous != null) b.previous.next = a;
a.next = b.next;
if (b.next != null) b.next.previous = a;
b.next = afterA;
if (afterA != null) afterA.previous = b;
b.previous = beforeA;
if (beforeA != null) beforeA.next = b;
}
// call it like this
swapNodes(dblLinkList.firstNode.next, dblLinkList.firstNode.next.next);
Are you sure it's c#? Looks like java. C# has LinkedListNode<T> class, not Node. And LinkedListNode<T> has Next and Previous properties. With capitals. And they are read only.
Any way c# implementation looks like this:
using System;
using System.Collections.Generic;
namespace LinkedListSwap
{
class Program
{
static void Main(string[] args)
{
var list = new LinkedList<string>(new[] { "1st", "2nd", "3rd", "4th", "5th", "6th", "7th" });
Console.WriteLine(list.ToDisplayString());
list.Swap(2, 3);
Console.WriteLine(list.ToDisplayString());
}
}
static class LinkedListExtensions
{
public static void Swap<T>(this LinkedList<T> list, int firstIndex, int secondIndex)
{
if (firstIndex < 1 || firstIndex > list.Count)
throw new IndexOutOfRangeException($"Index out of range: {nameof(firstIndex)}");
if (secondIndex < 1 || secondIndex > list.Count)
throw new IndexOutOfRangeException($"Index out of range: {nameof(secondIndex)}");
if (firstIndex == secondIndex)
return;
if (firstIndex > secondIndex)
(firstIndex, secondIndex) = (secondIndex, firstIndex);
int i = 0;
var leftNode = list.First;
while (++i < firstIndex)
leftNode = leftNode.Next;
var rightNode = leftNode.Next;
while (++i < secondIndex)
rightNode = rightNode.Next;
list.Replace(leftNode, rightNode);
list.Replace(rightNode, leftNode);
}
public static void Replace<T>(this LinkedList<T> list, LinkedListNode<T> oldNode, LinkedListNode<T> newNode)
{
list.AddAfter(oldNode, new LinkedListNode<T>(newNode.Value));
list.Remove(oldNode);
}
public static string ToDisplayString<T>(this LinkedList<T> list) => string.Join(" ", list);
}
}
Output is:
1st 2nd 3rd 4th 5th 6th 7th
1st 3rd 2nd 4th 5th 6th 7th
I'm trying to wrap my head around linked lists and I have this code sample here:
public class SinglyLinkedListNode {
public int data;
public SinglyLinkedListNode next;
public SinglyLinkedListNode(int data) {
this.data = data;
this.next = null;
}
public void Print() {
Console.WriteLine(data);
if(next != null) {
next.Print();
}
}
}
public class SinglyLinkedList {
public SinglyLinkedListNode headNode;
public SinglyLinkedList() {
headNode = null;
}
public void Print() {
if(headNode != null) {
headNode.Print();
}
}
}
class Program {
static void Main(string[] args) {
SinglyLinkedList list = new SinglyLinkedList();
int listCount = 5;
for(int i = 0; i < listCount; i++) {
int listItem = i + 1;
SinglyLinkedListNode list_head = InsertNodeAtTail(list.headNode, listItem);
list.headNode = list_head;
}
list.Print();
}
static SinglyLinkedListNode InsertNodeAtTail(SinglyLinkedListNode head, int data) {
if (head == null) {
head = new SinglyLinkedListNode(data);
return head;
} else {
var temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = new SinglyLinkedListNode(data);
return head;
}
}
}
in the InsertNodeAtTail method in the else statement where it's basically storing the passed in headNode as a temp variable and at the very end of it it set the temp variables next pointer to the new data were passing in and then return head. In this scenario how does head track the changes in the temp variable?
When I debug this and check the return head value it has all the changes that I've done to the temp variable but the head value was never really modified/used besides the part where it's being assigned to the temp variable.
Example is let's say we got a list 1 -> 3 -> 5 -> and were adding in 6
6 gets added into the temp.next and on return head, the head value contains 1 -> 3 -> 5 -> 6 but we've never done anything to head? All changes were to the temp variable.
Sorry if this might be a stupid question but I'm just not getting how this works.
Thanks
When I debug this and check the return head value it has all the changes that I've done to the temp variable but the head value was never really modified/used besides the part where it's being assigned to the temp variable.
temp is a reference to an SinglyLinkedListNode.
When you call the following code it keeps changing the reference of temp to the next SinglyLinkedListNode in the chain until you reach the last node. At this point temp is referring to the 5 in your example, and appends your new 6 to the end. No change is made to the head.
Since it is a chain 1 -> 3 -> 5, adding 6 to the end affects the whole chain and now becomes 1-> 3 -> 5 -> 6.
var temp = head;
while (temp.next != null) {
temp = temp.next;
}
I came across this singly linked list implementation in a book. However, I don't understand some statements. My questions against each statement are listed against each statement.
1 class Node {
2 Node next = null; //Is this a constructor?
3 int data;
4 public Node(int d) { data = d; }
5 void appendToTail(int d) {
6 Node end = new Node(d);
7 Node n = this;//Why is "this" keyword used here? What does this do?
8 while (n.next != null) { n = n.next; }//Where does "next" member come from?
9 n.next = end;
10 }
11 }
2 Node next = null; //Is this a constructor? NO it is not.
4 public Node(int d) { data = d; } //This is constructor
7 Node n = this; //The this keyword refers to the current instance of the class
8 while (n.next != null) { n = n.next; } //Learn Linked list
I have a table named Drinking.
Here is how it looks:
Name idCategory idParentCategory
drink 1 1
alcohol 2 1
nonalcohol 3 1
tea 5 3
juice 4 3
sparkling 6 4
nonsparkling 7 4
pepsi 8 6
schweppes 9 6
wine 10 2
beer 11 2
Now, the input is idCategory. As you can see there isn't property idChildren. What I am trying to do is find the ids of the children.
For example, if the input is 1, the output should be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.
Here is what I tried:
public void myMethod()
{
List<Drinking> drinkingList= (from d in myEntities.Drinking
select d).ToList();
foreach (var d in drinkingList)
{
if (d.Drinking2Reference.EntityKey != null)
{
s = c.Drinking2Reference.EntityKey.EntityKeyValues[0].Value.ToString();
idPD = Int32.Parse(s);
//get idParent
if (idPC == idCat)
{
//if idParent is equal as the input, put this idCategory
//in a list of integers.
//Now, here comes the tricky part.
//I should continue with this loop AND repeat this for
//every child of idPC.
//Where to put the call for this method?
//Where to put the return statement?
//Here is what I'm doing
myMethod(idPC);
}
else
{
myMethod(idPC);
}
}
}
}
My goal is to fill a list with the ids of the children and greatchildren
public void myMethod(int value)
{
List<int> intList = new List<int>();
List<Drinking> drinkingList= (from d in myEntities.Drinking
select d).ToList();
foreach (var d in drinkingList)
{
if (d.Drinking2Reference.EntityKey != null)
{
if(d.idCategory == value)
intList.Add(value);
else {
for(int i=0; i < intList.Count; i++) {
if(intList.ElementAt(i) == d.idParentCategory)
intList.Add(d.idCategory);
}
}
}
}
//Print numbers
}
I haven't tested this, but I feel like it should work. Feel free to comment if you catch something. Also, the table has to be sorted by idParentCategory for this to work. I will also say that with this situation I would recommend you look into using trees rather than a table.
Is there another way to do this? Just spent 2 hours trying to figure it out. I have a solution (see DumpPostOrder below) however, is there is a better or more efficient method? It feels like there may be. Rules are - no recursion, and the nodes cannot have a visited flag. Ie, you can only use left + right members.
My approach was to destroy the tree in the process. By setting the children of each side to null you can mark the node as traversed once, but I'm also looking at each node with children twice :(. Is there a better faster way? (Comments on my preorder and inorder implementations are appreciated but not necessary (ie, will vote, but not mark answer). Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BinaryTreeNoRecursion
{
public class TreeNode<T>
{
public T Value { get; set; }
public TreeNode<T> Left { get; set; }
public TreeNode<T> Right { get; set; }
public TreeNode(T inValue)
{
Value = inValue;
}
public TreeNode(TreeNode<T> left, TreeNode<T> right, T inValue)
{
Left = left;
Right = right;
Value = inValue;
}
}
public class BinaryTree<T>
{
private TreeNode<T> root;
public TreeNode<T> Root
{
get { return root; }
}
public BinaryTree(TreeNode<T> inRoot)
{
root = inRoot;
}
public void DumpPreOrder(T[] testme)
{
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
stack.Push(root);
int count =0;
while (true)
{
if (stack.Count == 0) break;
TreeNode<T> temp = stack.Pop();
if (!testme[count].Equals(temp.Value)) throw new Exception("fail");
if (temp.Right != null)
{
stack.Push(temp.Right);
}
if (temp.Left != null)
{
stack.Push(temp.Left);
}
count++;
}
}
public void DumpPostOrder(T[] testme)
{
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
TreeNode<T> node = root;
TreeNode<T> temp;
int count = 0;
while(node!=null || stack.Count!=0)
{
if (node!=null)
{
if (node.Left!=null)
{
temp = node;
node = node.Left;
temp.Left = null;
stack.Push(temp);
}
else
if (node.Right !=null)
{
temp = node;
node = node.Right;
temp.Right= null;
stack.Push(temp);
}
else //if the children are null
{
if (!testme[count].Equals(node.Value)) throw new Exception("fail");
count++;
if (stack.Count != 0)
{
node = stack.Pop();
}
else
{
node = null;
}
}
}
}
}
public void DumpInOrder(T[] testme)
{
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
TreeNode<T> temp = root;
int count = 0;
while (stack.Count!=0 || temp!=null)
{
if (temp != null)
{
stack.Push(temp);
temp = temp.Left;
}
else
{
temp = stack.Pop();
if (!testme[count].Equals(temp.Value)) throw new Exception("fail");
count++;
temp = temp.Right;
}
}
}
}
class Program
{
static void Main(string[] args)
{
//create a simple tree
TreeNode<int> node = new TreeNode<int>(100);
node.Left = new TreeNode<int>(50);
node.Right = new TreeNode<int>(150);
node.Left.Left = new TreeNode<int>(25);
node.Left.Right = new TreeNode<int>(75);
node.Right.Left = new TreeNode<int>(125);
node.Right.Right = new TreeNode<int>(175);
node.Right.Left.Left = new TreeNode<int>(110);
int[] preOrderResult = { 100, 50, 25, 75, 150, 125, 110, 175};
int[] inOrderResult = { 25, 50, 75, 100, 110, 125, 150, 175};
int[] postOrderResult = { 25, 75, 50, 110, 125, 175, 150, 100 };
BinaryTree<int> binTree = new BinaryTree<int>(node);
//do the dumps, verify output
binTree.DumpPreOrder(preOrderResult);
binTree.DumpInOrder(inOrderResult);
binTree.DumpPostOrder(postOrderResult);
}
}
}
Seems to me that destroying the tree while traversing it is pretty brutal.
You are currently building a Collection of nodes visited.
You are marking nodes as visited by setting them to null.
Could you not instead check for visitation by checking for the node in your Collection? For efficiency you may need to not use a Stack, but that's an implementation detail.
You could map your binary tree to an array (similar to how you can map a heap to an array, as shown here), and do your post-order traversal there. The action of converting a binary tree to an array is probably going to utilize recursion, but if you're controlling how the tree is initially constructed (or if you're just looking for an intriguing thought), you could just construct it as an array, and trivialize your non-recursive post-order traversal (with no flags) problem.
Edit
I think this would be a viable option:
1) Keep a bi-directional linked list of pointers to nodes in the tree.
2) Start at the root node.
3) Append root pointer to list.
4) Go to right child.
5) Append current node pointer to list.
6) Repeat steps 4 and 5 until there doesn't exist a right child.
7) Write current node to post-order-traversal.
8) Set current node to last node in the list.
9) Go to left child.
10) Append current note pointer to list.
11) Repeat steps 4 through 10 until the list is empty.
Basically, this makes all of the nodes in the tree have a pointer to their parent.
Avoiding recursion in this case is probably a bad idea, as previously noted. The system call stack is designed to handle things like this. Destroying your tree is a form of marking nodes.
If you want to use your own stack, then you need to push a bit more more information than just the node. Remember that the system call stack contains the program counter as well as the function parameters (local variables as well bu that is not important here). We could push tuples of the form (PushMyChildren, node), (PrintMe, Node), and when we pop a node of the form (PushMyChildren, node) we push (PrintMe, Node), then (PushMyChildren, right child) and then (PushMyChildren, left child). If the left and right children don't exist don't push them. When we pop a node of the form (PrintMe, Node) we print the node. In pseudo C# (I don't know C# and don't have time to look up the correct types and Syntax).
public void DumpPostOrder(T[] testme)
{
enum StackState {printNode, pushChildren}
Stack< Pair<StackState, TreeNode<T> > > stack = new Stack< Tuple<StackState, TreeNode<T> > >();
stack.Push(new Pair(pushChildren, root);
while ( stack.Count != 0 ) {
Pair<StackState, TreeNode<T> > curr = stack.pop();
if (curr.First == printNode) {
// process the node in curr.Second
} else {
node = curr.Second;
stack.Push(new Pair(printNode, node));
if (node.Right != null) {
stack.Push(new Pair(pushChildren, node.Right))
}
if (node.Left != null) {
stack.Push(new Pair(pushChildren, node.Left))
}
}
}
I just made post-order in Java using traversal to width (using queue).
private void init(){
if (initialized) return;
stack = new Stack<>();
stack.push(root);
travers(root.right);
travers(root.left);
initialized = true;
}
private void travers(Node node){
if (node == null) return;
Queue<Node> queue = new LinkedList<>();
queue.add(node);
while (!queue.isEmpty()){
Node temp = queue.poll();
stack.push(temp);
if (temp.right != null) queue.add(temp.right);
if (temp.left != null) queue.add(temp.left);
}
}
public T next() {
return stack.pop().data;
}