Convert to a complete BST function - c++

I need to save data in the bst to a sorted array, then, the ConvertToCompleteBST function clears current tree and uses the array to re-insert the values recursively by inserting the middle value in each call.
InsertRecursively(data_array,size);
For example, if the array was
[5 7 10 12 16 18 30]
then InsertRecursively([5 7 10 12 16 18 30],7) is called first,
the middle is 12 so 12 is the first one is inserted into the tree. Then in the recursive call , it will do the same but for
InsertRecursively([5 7 10],3)
InsertRecursively([16 18 30],3)
Then, InsertRecursively([5 7 10],3) will lead to inserting the node 7 and two other recursive calls
InsertRecursively([5],1) >> lead to inserting node 5
InsertRecursively([10],1) >> lead to inserting node 10
When size is 1, it will stop the recursive call.
I have no idea how to implement the insertRecursively function

Related

Bubble-sorting rows of Fortran 2D array

I am working on the second part of an assignment which asks me to reorder a matrix such that each row is in monotonically increasing order and so that the first element of each row is monotonically increasing. If two rows have the same initial value, the rows should be ordered by the second element in the row. If those are both the same, it should be the third element, continuing through the last element.
I have written a bubble sort that works fine for the first part (reordering each row). I have written a bubble sort for the second part (making sure that the first element of each row is monotonically increasing). However, I am running into an infinite loop and I do not understand why.
I do understand that the issue is that my "inorder" variable is not eventually getting set to true (which would end the while loop). However, I do not understand why inorder is not getting set to true. My logic is the following: once the following code has swapped rows to the point that the rows are all in order, we will pass through the while loop one more time (and inorder will get set to true), which will cause the while loop to end. I am stumped as to why this isn't happening.
inorder = .false.
loopA: do while ( .not. inorder ) !While the rows are not ordered
inorder = .true.
loopB: do i = 1, rows-1 !Iterate through the first column of the array
if (arr(i,1)>arr(i+1,1)) then !If we find a row that is out of order
inorder = .false.
tempArr = arr(i+1,:) !Swap the corresponding rows
arr(i+1,:) = arr(i,:)
arr(i,:) = tempArr
end if
if (arr(i,1)==arr(i+1,1)) then !The first elements of the rows are the same
loopC: do j=2, cols !Iterate through the rest of the row to find the first element that is not the same
if (arr(i,j)>arr(i+1,j)) then !Found elements that are not the same and that are out of order
inorder = .false.
tempArr = arr(i+1,:) !Swap the corresponding rows
arr(i+1,:) = arr(i,:)
arr(i,:) = tempArr
end if
end do loopC
end if
end do loopB
end do loopA
Example input:
6 3 9 23 80
7 54 78 87 87
83 5 67 8 23
102 1 67 54 34
78 3 45 67 28
14 33 24 34 9
Example (correct) output (that my code is not generating):
1 34 54 67 102
3 6 9 23 80
3 28 45 67 78
5 8 23 67 83
7 54 78 87 87
9 14 24 33 34
It is also possible that staring at this for hours has made me miss something stupid, so I appreciate any pointers.
When you get to compare rows where the first element is identical, you then go through the whole array and compare every single item.
So if you have two arrays like this:
1 5 3
1 2 4
Then the first element is the same, it enters the second part of your code.
In second place, 5>2, so it swaps it:
1 2 4
1 5 3
But then it doesn't stop. In third place, 4>3, so it swaps it back
1 5 3
1 2 4
And now you're back to where you were.
Cheers

why there is abnormalities in printing the key and value of un_ordered map and map(dictionary)?

here is my code please tell me why it is not printing from starting as in map it is printing in correct manner
#include<bits/stdc++.h>
using namespace std;
int main(){
unordered_map<int,int>arr;
for(int i=1;i<=10;i++){
arr[i]=i*i;
}
for(auto it=arr.begin();it!=arr.end();it++){
cout<<it->first<<" "<<it->second<<"\n";
}
cout<<"normal map \n";
map<int,int>arry;
for(int i=1;i<=10;i++){
arry[i]=i*i;
}
for(auto it=arry.begin();it!=arry.end();it++){
cout<<it->first<<" "<<it->second<<"\n";
}
}
and my output is
10 100
9 81
8 64
7 49
6 36
5 25
1 1
2 4
3 9
4 16
normal map
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
why un_ordered map printing the value in this fashion why not it printing like map
std::unordered_map doesn't order keys in any specific order. This is why it is called unordered.
Internally, the elements are not sorted in any particular order, but organized into buckets. Which bucket an element is placed into depends entirely on the hash of its key. This allows fast access to individual elements, since once the hash is computed, it refers to the exact bucket the element is placed into.

What is the tree-structure of a heap?

I'm reading Nicolai M. Josuttis's "The C++ standard library, a tutorial and reference", ed2.
He explains the heap data structure and related STL functions in page 607:
The program has the following output:
on entry: 3 4 5 6 7 5 6 7 8 9 1 2 3 4
after make_heap(): 9 8 6 7 7 5 5 3 6 4 1 2 3 4
after pop_heap(): 8 7 6 7 4 5 5 3 6 4 1 2 3
after push_heap(): 17 7 8 7 4 5 6 3 6 4 1 2 3 5
after sort_heap(): 1 2 3 3 4 4 5 5 6 6 7 7 8 17
I'm wondering how could this be figured out? for example, why the leaf "4" under path 9-6-5-4 is the left side child of node "5", not the right side one? And after pop_heap what's the tree structure then? In IDE debugging mode I could only see see the content of the vector, is there a way to figure out the tree structure?
why the leaf "4" under path 9-6-5-4 is the left side child of node "5", not the right side one?
Because if it was on the right side, that would mean there is a gap in the underlying vector. The tree structure is for illustrative purposes only. It is not a representation of how the heap is actually stored. The tree structure is mapped onto the underlying vector via a simple mathematical formula.
The root node of the tree is the first element of the vector (index 0). The index of the left child of a node is obtained from its parent's index by the simple formula: i * 2 + 1. And the index of the right child is obtained by i * 2 + 2.
And after pop_heap what's the tree structure then?
The root node is swapped with the greater of its two children1, and this is repeated until it is at the bottom of the tree. Then it is swapped with the last element. This element is then pushed up the tree, if necessary, by swapping with its parent if it is greater.
The root node is swapped with the last element of the heap. Then, this element is pushed down the heap by swapping with the greater of its two children1. This is repeated until it is in the correct position (i.e. it is not less than either of its children).
So after pop_heap, your tree looks like this:
----- 8 -----
| |
---7--- ---6---
| | | |
-7- -4- -5- x5
| | | | | | x
3 6 4 1 2 3 9
The 9 is not actually part of the heap anymore, but it is still part of the vector until you erase it, via a call pop_back or similar.
1. if the children are equal, as in the case of the adjacent 7's in the tree in your example, it could go either way. I believe that std::pop_heap sends it to the right, though I'm not sure if this is implementation defined
The first element in the vector is the root at index 0. Its left child is at index 1 and its right child at index 2. In general: left_child(i) = 2 * i + 1 and right_child(i) = 2 * i + 2 and parent(i) = floor((i - 1) / 2)
Another way to think about it is the heap fills each level from left to right in the tree. Following the elements in the vector the first level is 9 (1 value), second level 8 6 (2 values) and third level 7 7 5 5 (4 values), and so on. Both these ways will help you draw the heap in a tree structure when given a vector.

C++, How to create and draw a Binary Tree then traverse it in Pre-Order

How do I create a Binary Tree and draw it using a Pre-Order Traversal strategy? The root would be the first number going in.
I have a set of numbers: 48 32 51 54 31 24 39. 48 would be the root. How are the child nodes pushed onto the Binary Tree in a Pre-Order traversal?
Imagine the following sub-problem. You have a set of numbers:
N A1...AX B1...BY
You know that N is the root of the corresponding tree. All you need to know is what numbers form the left sub-tree. Obviously the rest of the numbers form the right sub-tree.
If you remember the properties of a binary-search trees, you would know that elements of the left sub-tree have values smaller than the root (while the ones on the right have values bigger).
Therefore, the left sub-tree is the sequence of numbers that are smaller than (or possibly equal to) N. The rest of the numbers are in the right sub-tree.
Recursively solve for
A1...AX
and
B1...BY
For example given:
10 1 5 2 9 3 1 6 4 11 15 12 19 20
You get:
root: 10
left sub-tree: 1 5 2 9 3 1 6 4
right sub-tree: 11 15 12 19 20
Say you have the following binary tree:
A
/ \
B C
/ \ / \
D E F G
/ \
H I
A Pre-Order Traversal goes NODE, LEFT, RIGHT.
So Pre-Order of this binary tree would be: A B D E H I C F G
For more details on how to implement this in C++: https://stackoverflow.com/a/17658699/445131

No O(1) operation to join elements from two forward_lists?

When reading about forward_list in the FCD of C++11 and N2543 I stumbled over one specific overload of splice_after (slightly simplified and let cit be const_iterator):
void splice_after(cit pos, forward_list<T>& x, cit first, cit last);
The behavior is that after pos everything between (first,last) is moved to this. Thus:
this: 1 2 3 4 5 6 x: 11 12 13 14 15 16
^pos ^first ^last
will become:
this: 1 2 13 14 3 4 5 6 x: 11 12 15 16
^pos ^first ^last
The description includes the complexity:
Complexity: O(distance(first, last))
I can see that this is because one needs to adjust PREDECESSOR(last).next = pos.next, and the forward_list does not allow this to happen in O(1).
Ok, but isn't joining two singly linked lists in O(1) one of the strengths of this simple data structure? Therefore I wonder -- is there no operation on forward_list that splices/merges/joins an arbitrary number of elements in O(1)?
The algorithm would be quite simple, of course. One would just need a name for the operation (pseudocode): (Updated by integrating Kerreks answer)
temp_this = pos.next;
temp_that = last.next;
pos.next = first.next;
last.next = temp_this;
first.next = temp_that;
The result is a bit different, because not (first,last) is moved, but (first,last].
this: 1 2 3 4 5 6 7 x: 11 12 13 14 15 16 17
^pos ^first ^last
will become:
this: 1 2 13 14 15 16 3 4 5 6 7 x: 11 12 17
^pos ^last ^first
I would think this is an as reasonable operation like the former one, that people might would like to do -- especially if it has the benefit of being O(1).
Am I overlooking a operation that is O(1) on many elements?
Or is my assumption wrong that (first,last] might be useful as the moved range?
Or is there an error in the O(1) algorithm?
Let me first give a corrected version of your O(1) splicing algorithm, with an example:
temp_this = pos.next;
temp_that = last.next;
pos.next = first.next;
last.next = temp_this;
first.next = temp_that;
(A sanity check is to observe that every variable appears precisely twice, once set and once got.)
Example:
pos.next last.next
v v
1 2 3 4 5 6 7 11 12 13 14 15 16 17 #
^ ^ ^ ^
pos first last end
becomes:
This: 1 2 13 14 15 16 3 4 5 6 7
That: 11 12 17
Now we see that in order to splice up to the end of that list, we need to provide an iterator to one before the end(). However, no such iterator exists in constant time. So basically the linear cost comes from discovering the final iterator, one way or another: Either you precompute it in O(n) time and use your algorithm, or you just splice one-by-one, also in linear time.
(Presumably you could implement your own singly-linked list that would store an additional iterator for before_end, which you'd have to keep updated during the relevant operations.)
There was considerable debate within the LWG over this issue. See LWG 897 for some of the documentation of this issue.
Your algorithm fails when you pass in end() as last because it will try to use the one-past-end node and relink it into the other list. It would be a strange exception to allow end() to be used in every algorithm except this one.
Also I think first.next = &last; needs to be first.next = last.next; because otherwise last will be in both lists.