find Kth element in a Binary Search tree - binary-search-tree

I'm learning about Binary Search Trees. I want to return the k-th element of the in-order traversal of the binary search tree. How can I keep the variable 'count' updated or is there some way to break out of the loop once I find the k-th element and print it out?
public void kthElement(int n, int count, BinaryNode<AnyType> root){
if( root.left !=null)
this.kthElement(n, count, root.left);
count++;
if(count==n){
System.out.println(root.element);
}
else if(count!=n){
return;}
if( root.right != null)
this.kthElement(n, count, root.right);
}

I can think of two solutions.
Declare a field for each node stating how many elements are in it's right subtree and left subtree, from here it should be easy to proceed.
If you're allowed to use additional memory, copy the elements to a dynamically allocated sorted array (using inorder traversal) and return the k'th element.

Related

Time complecity big O of modifided DFS (using DFS to search for path in maze)

I wrote a program that solves maze that is not ideal (has 1 or more correct paths) using recursion DFS algorithm. I have a problem with the time complexity of my program, becouse i read on the internet that the time complexity for DFS is O(v+n) where n is the number of node and v the number of edges. In my case if i don't find the correct path i go back and go the other bath if there is a branching, so i am thinking how it will affect my time complexity. NOTE(mazes that i use are directed graph, so i can't go back and have to go from up to down)
void DFS3 (int *visited, double **graf, int *paths, int **results, int n, int v, int end){
visited [ v ] = 1;
if(v==end){ // if we find the end we write the table of paths (our path) to the table of results
results[r][0]=k+1;
for(int j=1;j<k+1;j++)
results[r][j]=paths[j-1];
results[r][k+1]=end; // we write the last node (our wayout) to the table of results (it's not included in table of path)
r++;
visited[v]=0; // we mark the last node as not visited
}
for(int i = 1; i < n*n+1; i++ ){
if( ( graf [ v ][ i ] != 0 ) && visited [ i ] != 1 ){
paths[k]=v; // if we find the connection between node (a path) we write it to the paths and run the DFS3 of this node
k++;
DFS3 ( visited, graf, paths,results, n, i, end);
}
}
paths[k]=0; // if there is a dead end we go back to the first branching and delete the nodes that aren't correct path
k--;
visited[v]=0; // we mark them as unvisited
}
In DFS, as long as you are marking the nodes as already visited, you can avoid visiting them again. So, while you still have to evaluate all the edges (and there can be O(|V|^2 many directed edges), you don't have to go back down old paths.
If you want the shortest path through the maze (and not just the first one you happen to find), DFS is not great since you'd need to let it keep running to find all paths, then choose the shortest one. BFS will get you the shortest path first, but almost surely take longer to find a path through than DFS would. But, it's also O(|V| + |E|)

ClosestKeyBefore(k) in a BST

I am trying to find the closest key to k before k is reached in a binary search tree.
The more I think about it, the more I get confused as to where it could possibly be.
Formal definition of this method:
Return the key of the item with the largest key less than or equal to k
At first I thought it would be the parent of k.. but after looking at BSTs its becoming very unclear to me. I need the algorithm for this.
It should run in O(h) time where h is the height of the tree.
Thanks!
I guess you could make use of recursion to remember your current best value (ie. closest so far). If value is bigger than the current node, you search the right subtree and you know your current node is the best answer IF there is nothing found in right subtree. In the search of the right subtree, you return your current best answer (less than or equal) and this answer will just propagate up.
When value is less than current node, you search the left subtree. The current node cannot be your best answer because it is greater than the value you're searching. Hence just return whatever left subtree returns.
The code would look something like this. This is just a simple example with integers and it returns -1 when no valid values are found.
public static int closestKeyBefore(Node node, int val) {
if(node==null) return -1;
if(node.value == val) return val;
int retval = -1;
if(node.value<val) { // Value is bigger than current node, search right
retval = closestKeyBefore(node.right,val);
if(retval==-1) { //Not found in right subtree
retval = node.value; // Current node is the best answer. return this
}
}
else { // Value is smaller than current node, search left
retval = closestKeyBefore(node.left,val);
}
return retval;
}

Analysis of insert operation of an array-based list (cursor implementation)

So I'm studying for my algorithm analysis exam tomorrow and I'm reading over the instructors notes and examples. There's just one thing that I don't understand and it's this question:
Question: Inserting an element after a given element in an array-based list (cursor implementation) requires worst case time:
Answer: O(1)
Personally, I see the worst case being where the cursor is at the beginning of the list, therefore N-1 items in the array must be copied over to the next position before the new element is inserted and therefore it is an O(N) operation in the worst case.
However, when asked if this was a typo, the instructor stated that it wasn't.
What's the reasoning behind this? To all future answerers, thank you for your time.
Let's say we have to insert element 'a'. Well it says given an element, let's call it 'b'. What that means is you know what the next element is, let's call it 'c'. So all you have to do is to set the 'next' element of 'a' equal to 'c'. Then set the next element of 'b' equal to 'a'. This procedure is valid for any element. So the operation is constant time.
You can implement what is essentially a linked list using an array where each element in the array contains a pointer to the index of the next element.
struct Element
{
string item;
int next;
}
Given element A, you can insert a new element B after A in constant time.
int indexOfA = ..
int indexOfB = (next free index)
B.next = A.next;
A.next = indexOfB;

how to optimize search difference between array / list of object

Premesis:
I am using ActionScript with two arraycollections containing objects with values to be matched...
I need a solution for this (if in the framework there is a library that does it better) otherwise any suggestions are appreciated...
Let's assume I have two lists of elements A and B (no duplicate values) and I need to compare them and remove all the elements present in both, so at the end I should have
in A all the elements that are in A but not in B
in B all the elements that are in B but not in A
now I do something like that:
for (var i:int = 0 ; i < a.length ;)
{
var isFound:Boolean = false;
for (var j:int = 0 ; j < b.length ;)
{
if (a.getItemAt(i).nome == b.getItemAt(j).nome)
{
isFound = true;
a.removeItemAt(i);
b.removeItemAt(j);
break;
}
j++;
}
if (!isFound)
i++;
}
I cycle both the arrays and if I found a match I remove the items from both of the arrays (and don't increase the loop value so the for cycle progress in a correct way)
I was wondering if (and I'm sure there is) there is a better (and less CPU consuming) way to do it...
If you must use a list, and you don't need the abilities of arraycollection, I suggest simply converting it to using AS3 Vectors. The performance increase according to this (http://www.mikechambers.com/blog/2008/09/24/actioscript-3-vector-array-performance-comparison/) are 60% compared to Arrays. I believe Arrays are already 3x faster than ArrayCollections from some article I once read. Unfortunately, this solution is still O(n^2) in time.
As an aside, the reason why Vectors are faster than ArrayCollections is because you provide type-hinting to the VM. The VM knows exactly how large each object is in the collection and performs optimizations based on that.
Another optimization on the vectors is to sort the data first by nome before doing the comparisons. You add another check to break out of the loop if the nome of list b simply wouldn't be found further down in list A due to the ordering.
If you want to do MUCH faster than that, use an associative array (object in as3). Of course, this may require more refactoring effort. I am assuming object.nome is a unique string/id for the objects. Simply assign that the value of nome as the key in objectA and objectB. By doing it this way, you might not need to loop through each element in each list to do the comparison.

find the smallest depth leaf node in bst

Need to get the leaf node that has minimum depth. I cannot think of a good way to do it without storing additional information in each node, please suggest, thanks very much.
The brute force solution is a breadth-first search terminating at the first leaf found, this will be easier to implement iteratively than recursively.
See for instance the pseudo-code in my answer to "Breadth First Vs Depth First" just add another condition to the while-loop.
BTW--This will get you a leaf with the minimum depth, as there may be more than one at that depth. Getting the full set of minimum depth leaves is a little harder. I guess go with an iterative deepening strategy.
Finding out what level that node is one.
Three choices:
Find the node first and the search down the tree for it. It sounds wasteful, but that second search requires visiting only as many nodes as the level, so it really is fast.
Alternately you can keep track as you go. You use three counters levelCounter, thisLevelCounter and nextLevelCounter. Every time you more to a new node you decrement thisLevelCounter, and when it hits zero you've moved down a level so do
levelCounter++
thisLevelCounter = nextLevelCounter
nextLevelCounter = 0
Every time you add a child node to the search list, increment nextLevelCounter.
Every time you store a new child node increment nextLevelCounter
Finally, the iterative deepening strategy gives you the sucess level for free (which iteration finds it...) and has the same order of performance (though a slightly higher multiplier) as the breadth first search.
Here code version (hope I didn't miss any error check):
void min_leaf(node_t *t, int *min, int lev, node_t **n) {
if (!t) {
return;
}
if (lev > *min) {
printf("Back from %d at lev %d, min: %d already found\n",
t->key,
lev,
*min);
return;
}
if (!t->left && !t->right) {
if (*min > lev) {
*min = lev;
*n = t;
}
} else {
min_leaf(t->left, min, lev+1, n);
min_leaf(t->right, min, lev+1, n);
}
}
void bst_print_min_leaf(bst_t* bst) {
int min = 10000; /* Replace it with some really large number */
node_t *minn = NULL;
min_leaf(bst->root, &min, 0, &minn); /*level: root is level 0 */
if (minn) printf("min leaf is at depth: %d: (%p:%d)\n", min, minn, minn->key);
}