Building an incomplete binary tree - c++

I'm trying to build an incomplete binary tree from data provided in a text file
2
3 8
2 10 0 12
1 8 0 0 4 0
which would form a tree like this:
I know roughly what I need to do, I think:
read in from the file line-by-line.
pass an array to the build function.
As it's building the tree, the tree data type will keep track of the last nodes that it added in an array of pointers (eg, if we just finished adding the 3rd row of the text file, the a previous nodes array would look like pointers to the nodes containing [2 10 12]
as we start adding the 4th line, we create an array of 3*2=6 length to store pointers to the nodes as we add them.
we go through the array of pointers from the previous run (containing [2 10 12]) and create left and right children nodes for any non-zero keys that got passed through. We put pointers to those nodes in our 6-long array.
when we get a blank line, we're done.
The problem I'm running into is, I'm not sure how to store a array of pointers to nodes that changes size each time I call the build function and is a class variable (for the Tree class). Am I going about this the right way? Is there an easier way to approach this?

Like 2D array, array[row][column], you can use 2D vector ie. vector< vector<int> > V is a vector of vectors.
In vector< vector<int> > V, inside vector indicate row, and outside vector indicate column (for your understanding I just tell).
Here 2D vector is resize able. Not necessary that every column size will be equal. You can handle push, pop and you can store data according your memory size.
Example:
You can resize like of that:
int num_of_col = 5;
int num_of_row = 9;
double init_value = 3.14;
vector< vector<double> > matrix;
//now we have an empty 2D-matrix of size (0,0). Resizing it with one single command:
matrix.resize( num_of col , vector<double>( num_of_row , init_value ) );
// and we are good to go ...
You can learn here vector

Why don't you use a std::vector instead of array? It behaves exactly like an array but is resizable.
Example of usage:
using namespace std;
Node *a = new Node;
vector<Node*> vec;
vec.push_back(a);

Related

how to push_back vector with no size in a specific location?

I'm trying to get a solid understanding of Vectors. So i understand if we init vectors as following we specify the exact location in array for the vector to exist
vector<int> temp[5];
temp[i].push_back(randomInt);(i a random position)
but what if i'm trying to have a vector without specified size because i do not know the amount of input? how would i define the first index for example of temp as i did previously using the following init?
vector<int> temp;
here:
vector<int> temp[5];
you declared an array of 5 vectors, but going by your description it looks like you're meant to declare one vector with pre-allocated 5 elements (if so, then it should have been like vector<int> temp(5);)
how would i define the first index for example of temp as i did
previously using the following init?
all the std containers have methods allowing you to push / emplace data (i.e. to extend them) and method size() allowing to check the current size of the container.

Decrease array size after deletion of random item but keep the rest intact

Let's say we have an array of data and we do some stuff with the data.
At some point 1 of those data will be deleted for good, never to be seen again.
How do I remake the array again in a way that the item that I want to be deleted is gone and the rest of the array remains intact but with reduced size?
People are flagging me for duplicates, but it's not. I can't use vectors, because I have to make it work with arrays.
A way to do this is to create an array list.
int elements = 10;
int *arrayList= new int [elements]; //create first arraylist of size 10
int *arr2= new int [elements/2]; //create 2nd arraylist of size 5
for(int i=0; i<arr2.length; i++)
arr2[i]=arrayList[i]; //fill in the 2nd array
I followed #crashmstr answer which was the closest to what I wanted to do!
std containers.
Copying the entire array except for the deleted element wont do in large files because it adds process time, cycles, cache misses etc...
Thanks!

Inserting elements into 2D vector

so I'm creating a class that implements an adjacency list. Currently in my class definition I initialized two vectors:
vector<vector<int>> adjList;
vector<int> neighbors;
and I declared two functions that I plan to use to make it:
bool constructAdjList();
bool insertIntoAdjList(int, int);
It's getting difficult wrapping my head around 2D vectors. I understand that it is essentially a vector of vectors, but I'm confused about how to insert a new value into one of the "subvectors". For example, I am able to create an adjacency list in createAdjList that is empty with the following loop:
for (int i = 0; i < numOfValues; i++){
neighbors.push_back(0);
adjList.push_back(neighbors);
neighbors.clear();
}
But how can I say, push_back the value 5 to the 4th vector in adjList, which would be represented in my insertIntoAdjList function as
insertIntoAdjList(4, 5);
I know I can access a specific value in a 2D vector by saying adjList[4][1], but how can I push one onto it?
Thanks!
To push on the vector that is an element of another vector, you simply do this
adjList[x].push_back();
If initially you do not have any values in the vector -
You can push values into one vector and then push this vector into the 2D vector.
For example:
vector< vector<int> > vt1;
vector<int> vt2;
vt2.push_back(value);
vt1.push_back(vt2);
If your vector is already populated then -
vt1[index].push_back(value);
A couple of notes here.
Your loop can be significantly shortened just be using the constructors of your two members:
vector<int> neighbors(1, 0); // set to length 1, value is zero
vector<vector<int>> adjList(numOfValues,neighbors); // "outer" vector is numOfValues long
. // each row is a *COPY* of neighbor
If you can't do this at construction time (maybe numOfValues isn't known yet), then there's still a better loop phrasing we can use:
// neighbors object can be reused
neighbors.clear(0);
neighbors.push_back(0);
adjList.reserve(numOfValues); // reserving memory ahead of time will prevent allocations
for (int i = 0; i < numOfValues; i++){
adjList.push_back(neighbors); // push_back is by *COPY*
}
In your example, by using clear and push_back to essentially build the same vector every loop iteration, you are risking an allocation and deallocation each iteration. In practice, most implementations won't do this, but if we can both shorten and potentially make things more efficient, we may as well.
Lastly, if the number of neighbors is relatively small and similar row to row (for instance a finite elements code with tetrahedral elements, where each element connects to ~5 others), then as others have suggested you may be better off with a different structure than vector-of-vector. For instance, a single vector that is logically organized such that a new "row" begins every N elements.

Pointer to array as a whole

I have 4 arrays that I need to combine into 1 by adding all the corresponding cells. So I would add up Cell 1,1 (row 1, column 1) of all 4 matrices and put that into Cell 1,1 of the resultant matrix.
Well the 4 matrices are coming from another program and instead of writing an adder function that takes 4 matrices as the argument, I just had 1 vector. So my function looks like this:
void combine_matrix(vector<int*> all_arrays) {
vector<int> cell_values; //Vector that stores the value of a particular cell of each matrix
for (int i = 0; i<all_arrays[0].size(); i++)
}
vector<int*> all_arrays is a vector of pointers that points to the 4 arrays. This way, the matrices can be of any size (all 4 have to be the same dimensions though) and the function would still work.
Basicaly I want a vector of pointers pointing to the array as a whole so I can use the size() function but all the examples I've seen are only giving me pointers to the actual elements in the matrix. Any idea on how to do what I need? Thanks
Make a Matrix class that contains the pointer to array and the size and other things you might need to work with, and even better, make a CombinedMatrix class that contains vector<Matrix>

Does the array key determine array size in C++?

im storing some settings for objects in an array. the id's of objects are used as the key. the id's start from 100000 and go up. if i was to input data for an object with id 100 000, would cpp automatical create 99999 blank key entries starting from 0?
Array size is determined when you create an array.
To access object at index 100 000 you need to have array of at least that size, which answers your question.
If the array is smaller you will access memory at
array begin address + (index*object
size)
which is not a good thing. E.g. the following will print some data but it is a data that are stored at that point in memory and it's outside of your array (not a good thing):
string arr[3];
cout << arr[5] << endl;
Assuming you are talking about standard array like:
string arr[10];
Array's size is specified when you compile it, for example you can't do:
string arr[]; // this will fail to compile, no size specified
But you do:
string arr[] = {"1","2","3"}; // array size is 3
string arr1[3]; // array size is 3
string arr2[3] = {"1"}; // array size is 3
If you want to map extra parameters for object you are better off using std::map like:
class person {};
std::map<person*,int> PersonScore;
This assumes that the additional parameters are not logically part of the object otherwise you would just add them to the object.
Maybe you want somthing along the lines of:
class ArrayPlus100k {
Item underlyingArray[NUM_ELEMENTS];
public:
Item& operator [] (int i) { return underlyingArray[i-100000]; }
// etc.
}
If you truely mean an array, and by key you mean index, then subtracting 100,000 from your index will provide you with a zero based array index. There will be no unused entries.
There may be a better container than a flat array. Choosing the right data structure depends on what you are trying to do. If you are storing objects using a key, you might want to use a std::map<key, value>.
What happens depends entirely on the data structure you choose to use. If you use a map, only the items you insert will take up space in memory. If you use new to allocate an actual array, then you will want to allocate only enough space for for the items you want to store. In that case, adjust your index by subtracting 100,000.
No, it will not create 0-99999, but rather start from 100000 to your array size.
For example, if you declare the following:
int arr[5];
Starting from arr[2], you can store up to arr[7].
I hope you understand...