I am trying to implement 'Insertion Sort' on two queues without using an array.
Queue 1 - 4, 5, 11, 8, 3
Queue 2 - 2, 3, 4, 5, 2, 11
After the sorting they are as following :
Queue 1 - 3, 4, 5, 8, 11
Queue 2 - 2, 2, 3, 4, 5, 11
They get sorted. But I sort the queue like if it was a list. I do not know how to deal with a FIFO structure.
My teacher said that my implementation is alright if it was for a list, but not for queue. I am supposed to use the push() and pop() functions (already implemented them) and a third queue for assistance. This is my current implementation of the sorting algorithm:
void InsertionSort(queue* &left, queue* &right)
{
int x, i = 0, j;
queue *p = left;
while (p)
{
x = getElemAt(i, left, right);
j = i - 1;
while (j >= 0 && x < getElemAt(j, left, right))
{
setElemAt(j + 1, getElemAt(j, left, right), left, right);
j--;
}
setElemAt(j + 1, x, left, right);
p = p->next;
i++;
}
}
getElemAt and setElemAt are additional functions I've written separately. How should I approach the problem of sorting with an additional queue?
#interjay the queues need to be sorted individualy , with the use of a 3rd assisting queue which is used when queue1 or queue2 is sorted. The queues must not be sorted at the same time because this will require 2 assisting queues
Related
I can't wrap my head around what's missing in my function to populate a binary tree vs the manual input.
Printing the head value along with its left & right node value doesn't seem to help me as well since it looks correct to me. However, printing out all the values after auto populating it produces a strange result.
The values of this binary tree will be coming from an array:
std::vector<ValueType> values = {
3,
7,4,
2,4,6,
8,5,9,3
};
Here is the tree relation:
3
(7,4)
7 4
(2,4) (4,6)
2 4 6
(8,5) (5,9) (9,3)
As you can see, the parent node is located above and its children is below enclosed in parenthesis.
row1: the root node 3 have left:7, right:4
row2: parent 7 have left:2, right:4
row2: parent 4 have left:4, right:6
...
This may seem not be a binary tree as mentioned from the comments, but look at it as a tree having null left or right node or a node having a shared children from its sibling (same row).
Below is the function to automatically populate the binary tree:
// ValueType is defined as an alias of int
void populateTree(BinaryTree* node, int rowCount, int lastIndex, std::vector<ValueType> values) {
for (int i = 0; i < rowCount; ++i) {
iterCount++;
int currentRow = (i * (i + 1)) / 2;
int x = i + 1;
int nextRow = (x * (x + 1)) / 2;
bool toggle = false;
for (int j = nextRow; j < nextRow + x; ++j) {
auto value = values[currentRow++];
node->value = node->parent != nullptr ? value : node->value;
if (j >= values.size())
continue;
auto leftValue = values[j + 0];
auto rightValue = values[j + 1];
node->left = new BinaryTree(node, leftValue);
node->right = new BinaryTree(node, rightValue);
if (j != currentRow)
std::cout << ", ";
std::cout << node->value << "(" << node->left->value << "," << node->right->value << ")";
node = toggle ? node->right : node->left;
toggle = !toggle;
}
std::cout << std::endl;
}
}
I have used the triangular number formula to map the array into row and column.
Now, to confirm if the code is working, starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom should be 23.
I've done this by traversing bottom-up and add all the adjacent node combinations. Here's the output of the result:
3(7,4)
7(2,4), 4(4,6)
2(8,5), 4(5,9), 6(9,3)
iter count: 14
============
[4, 4, 7, 3]:18
[5, 4, 2, 4, 7, 3]:25
[3, 6, 4, 2, 4, 7, 3]:29
[3, 6, 4, 2, 4, 7, 3]:29
[5, 2, 4, 7, 3]:21
[4, 7, 3]:14
[4, 3]:7
pair total sum: 54
There supposed to be a combinations of [n1, n2, n3, ...nX]:23.
However, if I build the binary tree manually, there is a correct combination:
3(7,4)
7(2,4), 4(4,6)
2(8,5), 4(5,9), 6(9,3)
iter count: 14
============
[8, 2, 7, 3]:20
[5, 2, 7, 3]:17
[5, 4, 7, 3]:19
[9, 4, 7, 3]:23 <--- this is the correct combination.
[5, 4, 4, 3]:16
[9, 4, 4, 3]:20
[9, 6, 4, 3]:22
[3, 6, 4, 3]:16
pair total sum: 83
Link to full source code: https://gist.github.com/mr5z/8249a9101e5bfdce4850602c3ea7ebf3
This is part of my solution to project euler#18
I’m not exactly sure about why your implement a tree structure an your own, but if your goal is visualisation of a certain tree structure: I would suggest you to use the boost cpp graph library in combination with graphiz
See an example here, which shows the construction of a family tree, in a more "graph orientated" way. Every graph (like a tree) has nodes and edges.
If you want to train your programming skills, please go ahead: I found the following example for a b-tree quite useful in my past.
Couldn’t you use a “normal” insertIntoTree function instead of you populateTree function ? Or is this a matter of performance for you ?
What you do here is an example of an XY problem (see here: Meta StackExchange: What is the XY problem? or there: GreyCat's Wiki: XyProblem) – you're trying to put your data into a tree structure just because they are presented in a way resembling a tree-like pyramid, but you did not check if such structure will actually help you solve the problem.
And the answer is: NO, it will not; it doesn't even fit the actual problem structure.
Your problem structure is a pyramid-like triangle of integer numbers, each of which has two nearest descendants (except those in the bottom row) and two nearest ancestors (except those on side edges, which have just one ancestor, and the top item, which has no ancestors at all). And you have already mapped that structure into a linear array by your 'triangular formula':
given a row number r in a range of 0 .. N-1 and a position in the row p in a range of 0 .. r and an array with indices 0 .. N*(N+1)/2-1,
the item (r,p) is stored in the array at index r*(r+1)/2 + p,
and its 'children' are (r+1,p) and (r+1,p+1).
That's all, the mapping allows you to access data in a 'triangular' manner, you need no tree to handle it.
Given an n-ary tree stored in a parent array, with the children stored in an array of pointers to arrays where the first value is the number of children:
(childArray[2][0] shows that node 2 has 2 children, childArray[2][1] shows that its first child is 5, etc.)
parentArray = {3, 0, 3, -1, 3, 2, 2};
childArray = {{1, 1}, {0}, {2, 5, 6}, {3, 0, 2, 4}, {0}, {0}, {0}};
produces a tree that looks like this:
3
/|\
0 2 4
| |\
1 5 6
Using a queue, how can I output the tree level by level like so:
Level 1: 3
Level 2: 0, 2, 4
Level 3: 1, 5, 6
Levels 1 and 2 are easy, because level 1 is just the root and level 2 is just its children, but after that I can't figure out how to get it to get the children of the children.
One way of doing so would be using a queue data structure.
Start with some queue q, and place in the index of the (unique) item whose parent is -1. Now, at each step, until q is empty,
Perform v <- pop(q) (popping the head)
Print out v
For each child w of v, do push(q, v) (pushing ot the tail)
For example, here are the first steps for your case:
Initially, q = [3] (3 is the index of the item whose parent is -1).
We pop q, print out 3, and push 0, 2, and 4, so q = [0, 2, 4].
Now we pop q, print out 0, and push 1, so q = [2, 4, 1].
Almost by definition, since q is popped from the front and added to the back, the nodes will be processed level by level.
The complexity is linear in the number of nodes.
You will have to perform a BFS (Breadth First Search) on the tree, while maintaining the number of nodes pushed into the next level. Outline:
q.push(root); nodesInCurrentLevel = 1; nodesInNextLevel = 0; currentLevelIndex = 1;
while q is not empty do:
u = q.pop()
print currentLevelIndex and u
decrement nodesInCurrentLevel
for every child v of u do:
increment nodesInNextLevel
q.push(v)
if nodesInCurrentLevel is 0 do:
nodesInCurrentLevel = nodesInNextLevel
nodesInNextLevel = 0
increment currentLevelIndex
Of course, this would print the output as Level 2:0 Level 2:2, etc. You can store current level nodes in a temporary list within the loop and print as appropriate.
Suppose I have some sorted lists of integers and I want to convert them to their respective regex digit ranges, like so:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] => [0-9]
[0, 1, 2, 3, 4, 6, 7, 8, 9] => [0-46-9]
[0, 1, 3, 4, 5, 8, 9] => [013-589]
[0, 2, 4, 6, 8] => [02468]
I am not trying to regex match anything here. I am trying to generate a regex range from a set of digits.
I am really just looking to see if there is already some de facto algorithm for doing something like this.
Edit: Based on #Jerry_Coffin's answer, a Java-based algorithm:
List<Integer> digits = Arrays.asList(0, 1, 3, 4, 5, 8, 9);
StringBuilder digitRange = new StringBuilder().append('[');
int consecutive = 0;
for (int i = 0; i < digits.size(); i++) {
if (i == digits.size() - 1 || digits.get(i) + 1 != digits.get(i + 1)) {
if (consecutive > 1) {
digitRange.append('-');
}
digitRange.append(digits.get(i));
consecutive = 0;
} else {
if (consecutive == 0) {
digitRange.append(digits.get(i));
}
consecutive++;
}
}
digitRange.append(']');
System.out.println(digitRange.toString());
Output: [013-589]
Feel free to find improvements or problems.
Presumably you're starting from sorted input (if not, you almost certainly want to start by sorting the input).
From there, start from the first (unprocessed) item, write it out. Walk through the numbers as long as they're consecutive. Assuming you get more than two consecutive, write out a dash then the last of the consecutive numbers. If you got two or fewer consecutive, just write them to output as-is.
Repeat until you reach the end of the input.
I can propose a different approach.
Iterate through the list identifying intervals. We keep two variables left and right (interval bounds) and each time we have two not consecutive values we write the interval to a StringBuilder.
int[] list = new[] { 0, 1, 3, 4, 5, 8, 9 };
int left = 0;
int right = 0;
for (int i = 0; i < list.Length; i++)
{
if (i == 0) // first case
{
left = right = list[i];
continue;
}
if (list[i] - list[i - 1] > 1) // not consecutive
{
builder.AppendFormat(Write(left, right));
left = list[i];
}
right = list[i];
}
builder.AppendFormat(Write(left, right));// last case
builder.Append("]");
The write method:
private static string Write(int left, int right)
{
return
left == right
? left.ToString()
: right - left == 1
? string.Format("{0}{1}", left, right)
: string.Format("{0}-{1}", left, right);
}
This is a question I thought it would be easy but I found I'm wrong in the last. I can finish the program without recursive but I want to ask whether this problem can be finished in recursive version or not?
A recursive binary search tree traversal is basically (pseudo-code in case this is coursework):
def traverse (node):
if (node == NULL):
return
traverse (node.left)
doSomethingWith (node.payload)
traverse (node.right)
:
traverse (root)
That's all there is to it really, just replace doSomethingWith() with whatever you want to do (such as print).
That will traverse in left to right order so, if your BST is ordered in such a way that left means lower, simply swap over the two traverse calls.
By way of example, consider the following tree:
20
/ \
10 25
/ / \
5 24 27
/ /
2 28
as embodied in this example C program:
#include <stdio.h>
typedef struct s {
int payload;
int left;
int right;
} tNode;
tNode node[] = { // Trust me, this is the tree from above :-)
{20, 1, 4}, {10, 2, -1}, { 5, 3, -1}, { 2, -1, -1},
{25, 5, 6}, {24, -1, -1}, {27, -1, 7}, {28, -1, -1}};
static void traverse (int idx) {
if (idx == -1) return;
traverse (node[idx].right);
printf ("%d ", node[idx].payload);
traverse (node[idx].left);
}
int main (void) {
traverse (0);
putchar ('\n');
return 0;
}
Running that program gives you the following output:
28 27 25 24 20 10 5 2
Sure. Assuming the BST is sorted such that "greater than" nodes are on the right and "less than" nodes are on the left, a recursive function like this would work:
void recurse(Node* node)
{
if (node == nullptr) return;
recurse(node->right); // Explore all the "greater than" nodes first
std::cout << node->value << std::endl; // Then print the value
recurse(node->left); // Then explore "less than" nodes
}
My question is whether or not a heap can be "correct". I have an assignment asking me to do a heap sort but first build a heap using an existing array. If I look through the grader code it shows me that there is an exact answer. The way T implemented the heap build I get a slightly different answer but as far as i know is by definition a heap and therefore correct.
The "correct" array order is
{15, 12, 6, 11, 10, 2, 3, 1, 8}
but I get
{15, 12, 10, 11, 2, 6, 3, 1, 8}
The original vector is
{2, 8, 6, 1, 10, 15, 3, 12, 11}
void HeapSort::buildHeap(std::vector<CountedInteger>& vector)
{
std::vector<CountedInteger> temp;
for(int i = 0; i < vector.size(); i++)
{
temp.push_back(vector[i]);
fixDown(temp, i);
}
vector.swap(temp);
for(int i = 0; i < vector.size(); i++)
{
std::cout<< vector[i]<<std::endl;
}
}
void HeapSort::sortHeap(std::vector<CountedInteger>& vector)
{
}
inline unsigned int HeapSort::p(int i)
{
return ((i-1)/2);
}
void HeapSort::fixDown(std::vector<CountedInteger>& vector, int node)
{
if(p(node) == node) return;
if(vector[node] > vector[p(node)])
{
CountedInteger temp = vector[node];
vector[node] = vector[p(node)];
vector[p(node)] = temp;
fixDown(vector, p(node));
}
There are many possible ways to create a max-heap from an input. You give the example:
15, 12, 10, 11, 2, 6, 3, 1 8
15
12 10
11 2 6 3
1 8
It fulfills the heap criterion, so it is a correct max-heap. The other example is:
15, 12, 6, 11, 10, 2, 3, 1, 8
15
12 6
11 10 2 3
1 8
This also fulfills the heap criterion, so it is also a correct max-heap.
Max-heap criterion: Each node is greater than any of its child nodes.
A simpler example is 1, 2, 3, for which there are two heaps,
3 3
/ \ / \
1 2 2 1
Creating a heap out of an array is definitely an operation that can result in multiple different but valid heaps.
If you look at a trivial example, it is obvious that at least some subtrees of one node could switch positions. In the given example, 2 and 7 could switch positions. 25 and 1 could also switch positions. If the heap has minimum and maximum depth equal, then the subtrees of any node can switch positions.
If your grader is automatic, it should be implemented in a way to check the heap property and not the exact array. If your grader is a teacher, you should formally prove the correctness of your heap in front of them, which is trivial.