I want to traverse a Binary Tree vertically. And I found a working code in Geeks for Geeks in C++. I want to convert it into C# but I am unable to do so. Please guide me.
Below is my attempt:
// we always need the address of the Root Node come what may!
public class BstNode
{
public int data { get; set; }
public BstNode left { get; set; }
public BstNode right { get; set; }
public BstNode(int value) => data = value;
}
public class BstTree
{
// For BST
public BstNode Insert(BstNode root, int data)
{
if (root == null)
{
root = new BstNode(data);
root.left = null;
root.right = null;
}
else if (data > root.data)
root.right = Insert(root.right, data);
else root.left = Insert(root.left, data);
return root;
}
// PROBLEM IN BELOW CODE
public void VerticalOrderTraverse(BstNode root)
{
// Base case
if (root == null)
return;
// Create a map and store vertical oder in
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
int hd = 0;
// Create queue to do level order traversal.
// Every item of queue contains node and
// horizontal distance.
Queue<Tuple<BstNode, int>> que = new Queue<Tuple<BstNode, int>>();
que.Enqueue(new Tuple<BstNode, int>(root, hd));
while (que.Count != 0)
{
// pop from queue front
Tuple<BstNode, int> temp = que.Peek();
que.Dequeue();
hd = temp.Item2;
BstNode node = temp.Item1;
// insert this node's data in vector of hash
dict.Add(hd, new List<int>(node.data)); // CONFUSED HERE
if (node.left != null)
que.Enqueue(new Tuple<BstNode, int>(node.left, hd - 1));
if (node.right != null)
que.Enqueue(new Tuple<BstNode, int>(node.right, hd + 1));
}
foreach (var item in dict)
foreach (var ite in item.Value)
Console.WriteLine(ite);
}
}
class Program
{
public static void Main()
{
BstNode root = null;
BstTree bstTree = new BstTree();
root = bstTree.Insert(root, 10);
root = bstTree.Insert(root, 12);
root = bstTree.Insert(root, 7);
root = bstTree.Insert(root, 8);
root = bstTree.Insert(root, 15);
root = bstTree.Insert(root, 11);
root = bstTree.Insert(root, 6);
bstTree.VerticalOrderTraverse(root);
}
}
Kindly note that I am getting exception in "VerticalOrderTraversal" Method.
This VerticalOrderTraversal is exact replica of Vertical Order Traversal in C++
Exception: Key already exists in dictionary
EDIT:
After adding this check still the Logic does not give correct output
if (dict.ContainsKey(hd))
dict[hd].Add(node.data);
else dict.Add(hd, new List<int>(node.data));
Where you have this:
dict.Add(hd, new List<int>(node.data));
The original has this:
m[hd].push_back(node->key);
Now when we look up in documentation what the operator std::map::operator[] does, we find that
If k matches the key of an element in the container, the function returns a reference to its mapped value.
and importantly,
If k does not match the key of any element in the container, the function inserts a new element with that key
The indexer of Dictionary<TKey, TValue>.Item has the same capability ("a set operation creates a new element with the specified key"), but whereas in C++, this implies construction of a new vector as the value of the new element, C# does not create an instance of List<int> for us, so a simple solution could be:
if (dict.ContainsKey(hd))
dict[hd].Add(node.data);
else dict.Add(hd, new List<int>(node.data));
/// <summary>
/// We must calculate horizontal distance.
/// Each node along with its hd shall be queued.
/// Add hd and values in one hashset.
/// </summary>
/// <param name="root"></param>
public void VerticalOrderTraversal(Node<T> root)
{
if (root == null)
return;
int hd = 0;
Queue<Tuple<Node<T>,int>> q = new Queue<Tuple<Node<T>,int>>();
Dictionary<int, HashSet<T>> ht = new Dictionary<int, HashSet<T>>();
q.Enqueue(new Tuple<Node<T>, int>(root,hd));
ht[hd] = new HashSet<T>();
ht[hd].Add(root.Data);
while (q.Count > 0)
{
Tuple<Node<T>, int> current = q.Peek();
q.Dequeue();
if (current.Item1.leftNode != null)
{
if (!ht.ContainsKey(current.Item2 -1))
{
ht[current.Item2 - 1] = new HashSet<T>();
ht[current.Item2 - 1].Add(current.Item1.leftNode.Data);
}
else
{
ht[current.Item2 - 1].Add(current.Item1.leftNode.Data);
}
q.Enqueue(new Tuple<Node<T>, int>(current.Item1.leftNode, current.Item2 - 1));
}
if (current.Item1.rightNode != null)
{
if (!ht.ContainsKey(current.Item2 + 1))
{
ht[current.Item2 + 1] = new HashSet<T>();
ht[current.Item2 + 1].Add(current.Item1.rightNode.Data);
}
else
{
ht[current.Item2 + 1].Add(current.Item1.rightNode.Data);
}
q.Enqueue(new Tuple<Node<T>, int>(current.Item1.rightNode, current.Item2 + 1));
}
}
foreach (int key in ht.Keys)
{
foreach (T data in ht[key])
{
Console.WriteLine("Vertical Level " + key + " value " + data);
}
}
}
there are few changes I made to the original code:
If the level (hd) already exists in the Dict, we need to add the node to the end of the list not to insert a new tuple of level and list. so I added the if statement [if (dict.ContainsKey(hd))]
better use a sorted dictionary so that print will be from the least level not from the first level that was inserted.
In the original code, the list was created while inserting into the Dict, that was an issue because the node.data would be taken as the capacity of the list not as a data in the list.
public void VerticalOrderTraverse(BstNode root)
{
// Base case
if (root == null)
return;
// Create a map and store vertical oder in
SortedDictionary<int, List<int>> dict = new SortedDictionary<int, List<int>>(); //used Sorted Dictionary
int hd = 0;
Queue<Tuple<BstNode, int>> que = new Queue<Tuple<BstNode, int>>();
que.Enqueue(new Tuple<BstNode, int>(root, hd));
while (que.Count != 0)
{
Tuple<BstNode, int> temp = que.Peek();
que.Dequeue();
hd = temp.Item2;
BstNode node = temp.Item1;
if (dict.ContainsKey(hd)) //No need to try creating a new list, add it to the existing
dict[hd].Add(node.data);
else
{
dict.Add(hd, new List<int>());
dict[hd].Add(node.data);
}
if (node.left != null)
que.Enqueue(new Tuple<BstNode, int>(node.left, hd - 1));
if (node.right != null)
que.Enqueue(new Tuple<BstNode, int>(node.right, hd + 1));
}
foreach (var item in dict)
foreach (var ite in item.Value)
Console.WriteLine(ite);
}
}
}
}
public class Solution {
public IList<IList<int>> result = new List<IList<int>>();
public SortedDictionary<int, List<int>> IndexingItems = new SortedDictionary<int, List<int>>();
public IList<IList<int>> VerticalTraversal(TreeNode root)
{
if(root == null) return result;
Queue<(int, TreeNode)> queue = new Queue<(int, TreeNode)>();
int hDis = 0;
queue.Enqueue((hDis, root));
while(queue.Count != 0)
{
(int, TreeNode) qTop = queue.Peek();
queue.Dequeue();
hDis = qTop.Item1;
TreeNode current = qTop.Item2;
AddItemToDictionary(hDis, current);
if(current.left != null)
{
queue.Enqueue((hDis - 1, current.left));
}
if(current.right != null)
{
queue.Enqueue((hDis + 1, current.right));
}
}
foreach(var item in IndexingItems)
{
var value = item.Value as List<int>;
result.Add(value);
}
return result;
}
public void AddItemToDictionary(int hDis, TreeNode node)
{
if(IndexingItems.ContainsKey(hDis))
{
IndexingItems[hDis].Add(node.val);
// Console.WriteLine($"Updating {hDis} value");
}
else
{
// Console.WriteLine($"Adding new item {hDis} to Dictionary with {node.val} value");
IndexingItems.Add(hDis, new List<int>(){ node.val });
}
}
}
I tried with this approach. But I am not sure, why there is a few mismatch in the order of the data for same nodes.
Related
I have an XML file from which dynamically creates a JSON. The last entry in each row should get a value when the JSON is finished.
However when the JSON is finished only the last entry from the last row has a value. I guess its overwriting since I need to recreate every entry for the right JSON structure.
I split the Group of each row and each point is a JObject except the one with "[0]", thats a JArray.
Has anyone an idea how I can avoid overwriting my JObjects? Thanks.
My XML
My JSON
private static void GenerateElement(JObject parent, string path, string value)
{
var parts = path.Split('.');
foreach (var item in parts)
{
var partsCount = parts.Count();
var currentElement = item;
if (partsCount > 1)
{
path = path.Remove(0, item.Length);
if (path.StartsWith("."))
{
path = path.Remove(0, 1);
}
else if (path.EndsWith("."))
{
path = path.Remove(path.Length - 1, 1);
}
parts = path.Split('.');
}
var nextElementPath = path;
var elementArrayName = currentElement;
if (currentElement.IndexOf("[0]") >= 0)
{
elementArrayName = currentElement.Substring(0, currentElement.IndexOf("[0]"));
}
else
{
parent[currentElement] = new JObject();
}
if (partsCount > 1)
{
if (parent[nextElementPath] == null)
{
if (parent[elementArrayName] == null)
{
parent[elementArrayName] = new JArray();
(parent[elementArrayName] as JArray).Add(new JObject());
}
}
if (parent[elementArrayName] is JArray)
{
parent = parent[elementArrayName][0] as JObject;
}
else
{
parent = parent[currentElement] as JObject;
}
}
else
{
parent[currentElement] = value;
}
}
}
In Python I can convert a binary tree structure to an arbitrary nested List:
great
/ \
gr eat
/ \ / \
g r e at
/ \
a t
[great, [gr, [g, r], eat, [e, at, [a, t]]]
Is there a way to build an arbitrary nested List in C#?
EDIT: I took a BinaryTree<T> class from MSDN docs as a base class for my custom StrBinaryTree class. Method FormTree is doing a job for creating a tree structure from a string:
public class StrBinaryTree : BinaryTree<string>
{
public StrBinaryTree(string data)
{
if (data.Length == 0)
{
base.Root = null;
base.Count = 0;
}
else
{
base.Root = new BinaryTreeNode<string>();
base.Root.Data = data;
base.Count = 1;
}
}
public void FormTree(BinaryTreeNode<string> node)
{
var subLength = node.Data.Length / 2;
if (subLength == 0)
return;
node.Left = new BinaryTreeNode<string>(node.Data.Substring(0, subLength));
node.Right = new BinaryTreeNode<string>(node.Data.Substring(subLength));
base.Count += 2;
FormTree(node.Left);
FormTree(node.Right);
}
...}
I would use recursion to go through the tree. Since you didn't told us the type of the tree we cannot provide you c# sample code.
But it would be something like this:
void List<Object> GetNestedListFromTree(Tree tree, List<Object> list = null)
{
List<Object> curList;
if (!tree.HasChildNodes)
return list;
else
{
if (list==null)
{
list = new List<Object>;
curList = list;
}
else
{
curList = new List<Object>;
list.Add(curList);
}
foreach(node in tree.ChildNodes)
{
curList.Add(node.Name);
curList.Add(GetNestedListFromTree(node.GetSubtree, curList));
}
return curList;
}
}
This isn't tested because I don't know your tree but yeah ... It should work if your tree can provide the needed functionality.
Try this solution
public static List<object> Solve(string input, List<object> list = null)
{
if (list == null)
return Solve(input, new List<object> { input });
if (input.Length > 1)
{
var middle = input.Length / 2;
var first = input.Substring(0, middle);
var second = input.Substring(middle);
var innerList = new List<object>();
list.Add(innerList);
foreach (var side in new[] { first, second })
{
innerList.Add(side);
Solve(side, innerList);
}
}
return list;
}
public static void Show(object input)
{
if (!(input is string))
{
Console.Write("[");
var list = input as List<object>;
foreach (var item in list)
{
Show(item);
if (item != list.Last())
Console.Write(", ");
}
Console.Write("]");
}
else
Console.Write(input);
}
Usage:
var result = Solve("great");
Show(result);//[great, [gr, [g, r], eat, [e, at, [a, t]]]]
Approximate code for BinaryTreeNode:
public static BinaryTreeNode<string> Solve(BinaryTreeNode<string> node)
{
if(node.Data.Length > 1)
{
var middle = node.Data.Length / 2;
var left = node.Data.Substring(0, middle);
var right = node.Data.Substring(middle);
node.Left = Solve(new BinaryTreeNode<string>(left));
node.Right = Solve(new BinaryTreeNode<string>(right));
}
return node;
}
Usage:
var result = Solve(new BinaryTreeNode<string>("great"));
Try this:
public Tree<string> Build(string text)
{
var tree = new Tree<string>() { Value = text };
if (text.Length > 1)
{
tree.Add(Build(text.Substring(0, text.Length / 2)));
tree.Add(Build(text.Substring(text.Length / 2)));
}
return tree;
}
public class Tree<T> : List<Tree<T>>
{
public T Value;
public override string ToString()
{
var r = $"\"{this.Value}\"";
if (this.Any())
{
r += $" [{String.Join(", ", this.Select(t => t.ToString()))}]";
}
return r;
}
}
When I run Build("great") I get:
"great" ["gr" ["g", "r"], "eat" ["e", "at" ["a", "t"]]]
I am following some tutorial go implementing linkedlist in C#. This is my code which i copied from that tutorial.
internal class Node
{
internal int data;
internal Node next;
public Node(int d)
{
data = d;
next = null;
}
}
internal class SingleLinkedList
{
public void printAllNodes()
{
Node current = head;
while (current != null)
{
Console.WriteLine(current.data);
current = current.next;
}
}
internal Node head;
internal void InsertFront(SingleLinkedList singlyList, int new_data)
{
Node new_node = new Node(new_data);
new_node.next = singlyList.head;
singlyList.head = new_node;
}
internal void InsertLast(SingleLinkedList singlyList, int new_data)
{
Node new_node = new Node(new_data);
if (singlyList.head == null)
{
singlyList.head = new_node;
return;
}
Node lastNode = GetLastNode(singlyList);
lastNode.next = new_node;
}
internal Node GetLastNode(SingleLinkedList singlyList)
{
Node temp = singlyList.head;
while (temp.next != null)
{
temp = temp.next;
}
return temp;
}
internal void InsertAfter(Node prev_node, int new_data)
{
if (prev_node == null)
{
Console.WriteLine("The given previous node Cannot be null");
return;
}
Node new_node = new Node(new_data);
new_node.next = prev_node.next;
prev_node.next = new_node;
}
}
}
Now i Added some nodes and displaying it which is working very fine.
SingleLinkedList obj = new SingleLinkedList();
obj.InsertFront(obj, 7);
obj.printAllNodes();
obj.InsertFront(obj, 9);
obj.printAllNodes();
obj.InsertLast(obj, 345);
obj.printAllNodes();
Now i want to use that "InsertAfter" function which i am using but it is not working correctly , it is still showing the old nodes.What's wrong with it?
obj.InsertAfter(new Node(7), 10);
obj.printAllNodes();
Maybe this is your requirement:
SingleLinkedList obj = new SingleLinkedList();
obj.InsertFront(obj, 7);
obj.InsertFront(obj, 9);
var d = obj.GetLastNode(obj);
obj.InsertLast(obj, 345);
obj.InsertAfter(d, 44);
obj.printAllNodes();
I think this is the best solution if you don't change the class SingleLinkedList. But if I were you, I would consider editing that class.
EDIT:
I would implement "insert" methods like this:
internal Node InsertFront(SingleLinkedList singlyList, int new_data)
{
Node new_node = new Node(new_data);
new_node.next = singlyList.head;
singlyList.head = new_node;
return new_node;
}
So that instead of calling obj.InsertFront(obj, 7); I would call Node node = obj.InsertFront(obj, 7); and it would then help me to insert node after any node: obj.InsertAfter(node, 44);
I want to know if there is any way to store value of an enumerator of key value pairs while iterating through a dictionary. I want to store the key and value of an enumerator in some variable. What is the solution? What I wanted to do is while iterating through dictionary to have a reference of the current key value pair and the next keyvalue pair in the dictionary.I dont know why it is not working
Here is what the solution might look like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;
namespace WellPuzzle
{
class Solution
{
Hashtable h1 = new Hashtable();
List<int> listofitemstoremove = new List<int>();
Dictionary<int, int> d1 = new Dictionary<int, int>();
public void falling_disks(int[] A, int[] B)
{
var itemstoremove = new List<int>();
var en = d1.GetEnumerator();
int count = 0;
for (int i = 0; i <= A.Length - 1; i++)
{
d1.Add(count++, A[i]);
}
//for each incoming element in array
foreach (int ele in B)
{
//store prev as current position of enumerator
var prev = new KeyValuePair<int, int>();
prev = en.Current;
//check if it is possible to iterate to next element in dictionary
if (en.MoveNext())
{
//loop till end of dictionary
while (en.MoveNext())
{
//if current value of enumerator in dictionary is less than incoming element and check if corroesponding key for that value is in hashtable or not
if (en.Current.Value <= ele && !(checkifthatvalueisfilled(en.Current.Key)))
continue;
else
{//if current enumerator value is greater than incoming element from array B then remove all elements from prev reference till end of dictionary
h1.Add(en.Current.Key, true);
listofitemstoremove.Add(en.Current.Key);
}
prev = en.Current;
}
if (!(h1.ContainsKey(en.Current.Key)))
{
h1.Add(en.Current.Key, true);
listofitemstoremove.Add(en.Current.Key);
}
}
else
{
h1.Add(prev.Key, true);
listofitemstoremove.Add(prev.Key);
}
foreach (int item in listofitemstoremove)
{
for (int i = item; i < d1.Count; i++)
{
d1.Remove(i++);
}
}
}
Console.WriteLine(h1.Count);
}
public bool checkifthatvalueisfilled(int value)
{
if (h1.ContainsValue(h1.ContainsKey(value)) == true)
return true;
else return false;
}
}
class Program
{
static void Main(string[] args)
{
int[] A = new int[] { 5, 6, 4, 3, 6, 2, 3 };
int[] B = new int[] { 2, 3 };
Solution s1 = new Solution();
s1.falling_disks(A, B);
}
}
}
It seems like you want to be able to access the previous value as well as the current value of the sequence. Here is a simple helper method that takes a sequence and turns it into a sequence of pairs that represents each value with it's previous value in the original sequence:
public static IEnumerable<Tuple<T, T>> GroupAdjacent<T>(IEnumerable<T> source)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
T previous = iterator.Current;
while (iterator.MoveNext())
{
yield return Tuple.Create(previous, iterator.Current);
}
}
}
It could then be used like:
foreach(var pair in GroupAdjacent(dictionary))
{
var previous = pair.Item1;
var current = pair.Item2;
}
Is there a good reason you cannot use:-
// Replace TKey and TValue with the types from the dictionary
TKey previousKey;
TValue previousValue;
bool first = true;
foreach(var key in dictionary.Keys)
{
var value = dictionary[key];
if (!first)
{
... // Do whatever you need to do with the keys and values
}
previousKey = key;
previousValue = value;
first = false;
}
(Note, though, that you'll likely have to .OrderBy(...) your .Keys for this to make any sense)
List<KeyValuePair<Int32, Int32>> keyValuePairsWithIterations = new List<KeyValuePair<Int32, Int32>>();
foreach(var keyvaluepair in d1)
{
keyValuePairsWithIterations.Add(keyvaluepair);
}
Now you can access your keyvaluepairs by iteration. But it look a little bit strengh... And I still dont understand for what you need it...
As well as Iain's and the other's approaches, you can also do it like this (like Iain's, this gives previous and current rather than current and next, but they are pretty much the same thing):
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
private static void Main(string[] args)
{
var d1 = new Dictionary<int, int> {{1, 1}, {2, 2}, {3, 3}, {4, 4}};
bool isFirst = true;
var previous = new KeyValuePair<int, int>();
foreach (var current in d1)
{
if (!isFirst)
{
// You have current and previous available now.
Console.WriteLine("Current = " + current.Value + ", previous = " + previous.Value);
}
previous = current;
isFirst = false;
}
}
}
}
And here's how you can do it by manually using the enumerator:
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
private static void Main(string[] args)
{
var d1 = new Dictionary<int, int> {{1, 1}, {2, 2}, {3, 3}, {4, 4}};
var iter = d1.GetEnumerator();
if (iter.MoveNext())
{
var previous = iter.Current;
while (iter.MoveNext())
{
// You have current and previous available now.
Console.WriteLine("Current = " + iter.Current.Value + ", previous = " + previous.Value);
previous = iter.Current;
}
}
}
}
}
Why do you need an iterator? The foreach loop will do that for you.
If you need the current and previous item, you could just store the previous item in every iteration:
Dictionary<int, int> d1 = new Dictionary<int, int>();
KeyValuePair<int, int> previous = null;
KeyValuePair<int, int> current = null;
foreach (KeyValuePair<int, int> item in d1)
{
previous = current;
current = item;
// do what you need to do with previous and current
}
You could also use a SortedDictionary, that will give you an index.
I am working on creating my own LinkedList. But I can't seem to solve this error. Can anyone help me!
The problem is that I want to insert an object after a particular element. I have created Find method to search for that particular item and return its reference, but I can't seem to solve it.
CustomLinkedList c = new CustomLinkedList();
c.Add(31);
c.Add(45);
c.Add(23);
c.Add(36);
c.PrintList();
Console.WriteLine("\n" + " Process of adding item at a spectifed location");
c.Addafter(66,23);
c.PrintList();
class Node
{
public object Element;
public Node Link;
public Node()
{
Element = null;
Link = null;
}
public Node(object TheElement)
{
Element = TheElement;
Link = null;
}
class CustomLinkedList
{
protected Node header;
protected Node last;
public CustomLinkedList()
{
//header = new Node("header");
}
private Node Find(object Item)
{
Node Current = new Node();
Current = header;
while (Current.Element != Item && Current.Link !=null)
{
Current = Current.Link;
}
return Current;
}
public void PrintList()
{
Node n = new Node();
n = header;
while (n != null)
{
Console.WriteLine(n.Element);
n = n.Link;
}
}
public void Add(object a)
{
Node n = new Node();
n.Element = a;
n.Link = null;
if (last == null)
{
header = n;
last = n;
}
else
{
last.Link = n;
last = n;
}
}
public void Addafter(object newitem, object After)
{
Node current = new Node();
Node newNode = new Node(newitem);
current = Find(After);
newNode.Link = current.Link;
current.Link = newNode;
}
}
The reason why it doesn't work is on this line:
while (Current.Element != Item && Current.Link !=null)
The == and != operators for the object type check for reference equality. If you're using your list with a value type (int for instance), the values will be boxed to distinct objects, and the != operator will always return true (see this article for details about boxing).
Consider this:
object x = 42;
object y = 42;
Console.WriteLine(x == y); // prints False
Console.WriteLine(x.Equals(y)); // prints True
Your current code is working fine with reference types:
var list = new CustomLinkedList();
list.Add("hello");
list.Add("!");
list.Addafter("world", "hello");
list.PrintList();
Output:
hello
world
!
But for value types it never finds the "after" value, so it appends the new item to the end of the list:
var list = new CustomLinkedList();
list.Add(1);
list.Add(3);
list.Addafter(2, 1);
list.PrintList();
Output:
1
3
2
So you need to replace the == operator with a call to Equals:
while (!object.Equals(Current.Element, Item) && Current.Link !=null)
I don't know what you're using for testing but value types won't work the way you think it should because the box values are being compared.
For example this will always return 3 (last element in list)
CustomLinkedList cList= new CustomLinkedList();
cList.Add(1);
cList.Add(2);
cList.Add(3);
Console.WriteLine(cList.Find(2).Element);
but this will work (output 2)
CustomLinkedList cll = new CustomLinkedList();
object a = 1;
object b = 2;
object c = 3;
cll.Add(a);
cll.Add(b);
cll.Add(c);
Console.WriteLine(cll.Find(b).Element);
The same goes for reference types that don't implement the != operators. So strings will work but little else will
Your code has 2 problems
The Find() function is returning the Tail element when the Item is not in the List.
Comparing n.Element and Item is tricky when they are of type object. Make your classes generic to solve that.
...
class CustomLinkedList<T> where T : IEquatable
{
....
private Node Find(object Item)
{
Node Current = header; // null for empty list
//while (Current.Element != Item && Current.Link !=null)
while(Current != null)
{
if (Current.Equals(Item) ) // can't always use ==
break;
Current = Current.Link;
}
return Current;
}
}