Storage elements from binary tree in array - arrays

I want to store my elements from my binary tree into an array but have no idea how to do it...
I already have a count method for the size of my array, now i need to store my int elements into an array
public int countNode() {
if (this.root == null) {
return 0;
} else {
int count = 1;
count += root.l.countNode();
count += root.r.countNode();
return count;
}
}
public int[] arrayStorage() {
int[] a = new int[countNode()];
}

You can add it to array by level order traversing the tree using queue.
The main reason we don't follow this approach for a binary tree is that this wastes a lot of space in array when the tree isn't complete unlike a heap.

Related

Making a Directed Acyclic Graph

I'm working on a task, where the final step is to take an array of pairs (where a pair is essentially an edge in a graph) and make an Acyclic graph from it. If a pair happens to create a cycle in the graph, then it should be skipped. The DAG is to be stored as an adjacency matrix (the edges are unweighted, hence it is of type bool matrix[][] )
I tried to implement a modified DFS, based on what I read online. The task is in C, and I'm new to the language, so sorry for the crudeness of the code.
The point is that it doesn't skip the cycle-forming pairs and I'm stuck at this point. Any advice or help is appreciated.
int MAX; //number of nodes in the graph
int player; //a node in the graph
typedef struct
{
int winner;
int loser;
} pair; //a directed edge from player 'winner' to player 'loser'
pair pairs[MAX * (MAX - 1) / 2]; //array of all valid pairs
int main(void)
{
/* Get input from console for:
MAX - desired number of players, <= 9,
. . .
int results[MAX][MAX]; - a table (2D array), where each element
results[A][B] shows the number of wins that player A
has over player B, and vice versa.
Element results[X][X] = 0 always.
A new pair is only added when two players have unequal
number of wins over each other: results[A][B] != results[B][A],
so that pairs[i].winner is the one having more wins than losses
against pairs[i].loser .
pairs[] is then sorted in descending order according to
the value of pairs[i].winner .
The goal is to create another 2D array
bool matrix[MAX][MAX];
by adding each pair in pairs[] sequentially,
so that matrix[][] is the adjacency matrix of a
Directed Acyclic Graph. (a.k.a. if a pair happens to create
a cycle, it must not be added)
*/
DAG();
}
void DAG(void)
{
int from, to;
for (int i = 0; i < pair_count; i++)
{
//Create an edge in graph
from = pairs[i].winner;
to = pairs[i].loser;
matrix[from][to] = true;
//Check if this edge made a cycle
bool visited[MAX];
bool onStack[MAX];
if (cyclicGraph(visited, onStack))
{
matrix[from][to] = false;
}
//Here we should have the DAG in locked
return;
}
bool cyclicGraph(bool visited[], bool onStack[])
{
for (int k = 0; k < MAX; k++)
{
//Run the hasCycle-DFS only from unvisited vertices
if (!visited[k] && hasCycle(k, visited, onStack))
{
//if it forms a cycle,
return true;
}
}
return false;
}
bool hasCycle(int x, bool visited[], bool onStack[])
{
// we push this 'x' node onto the stack
onStack[x] = true;
int child;
for (int i = 0; i < MAX; i++)
{
if (locked[x][i]) //x's children are only i's holding True values in array "locked[x][i]"
{
child = i;
if (onStack[child])
{
return true;
}
if (!visited[child] && hasCycle(child, visited, onStack))
{
return true;
}
}
}
//we pop the 'x' from the stack and mark it as visited
onStack[x] = false;
visited[x] = true;
return false;
}
I went back to this problem after a while and I found the bug. The two arrays bool visited[MAX]; bool onStack[MAX]; holding the information for the nodes being visited or being on the recursion stack during the DFS hadn't been initialized. A simple solution is to initialize them with false values:
memset(visited, false, sizeof visited);
memset(onStack, false, sizeof onStack);
Conclusion: always make sure to initialize your variables.

Consolidating partitions / aka Compaction algorithm

Given number of partitons (usedSpace and its totalSpace) of a hard disk in the form of an list
Example usedSpace = [3,2,1,3,1]
totalSpace = [3,5,3,5,5]
Here usedSpace is the partition getting used out of total space on that partition.
Find the minimum number of partitions need to hold all the data if we move data around partition optimally.
In this cases
a) move data from 1st partion to 2nd partition and 1st partition will be empty
b) move data of 3rd and 5th partition to 4th partition and 3rd and 5th will be free.
Hence only 2 partition needed to hold all the data.
Since the number of moves doesn't matter, and since data can be split up, a greedy approach will work. Pseudocode:
partitionCount := 0
# We're only worried about the total space used vs the total space available
unallocatedDataSize := sum of elements in usedSpace
# Greedily use the largest available space
sort totalSpace by size, descending
while unallocatedDataSize > 0 and totalSpace is not empty
partitionSize := totalSpace.removeFirst()
partitionCount := partitionCount + 1
# Storing partitionSize data in this partition, remove it from our tracking
unallocatedDataSize = unallocatedDataSize - partitionSize
return partitionCount
An optimal and working solution in C#:
public int getMinDrives(int[] used, int[] total)
{
int hdQty = 1;
int pos = 0;
int currentTotal;
Array.Sort(total);
Array.Reverse(total);
int usedSum = used.Sum();
while (usedSum > 0)
{
currentTotal = total[pos];
usedSum = usedSum - currentTotal;
if (usedSum > 0)
{
hdQty++;
pos++;
continue;
}
}
return hdQty;
}
How this can be resolved by Java, if the function returning as Integer value containing args of the amount of used space on each partition and total capacity of each partition, like :
int minPartition(List<Integer> used, List<Integer> totalCapacity), how one can resolve by the above answer supplied by Greedy approach?
The below code responds to Heap space error if i checked with above:
import java.util.ArrayList;
import java.util.List;
public class Program3 {
public static void main(String[] args) {
List<Integer> used = new ArrayList<>();
List<Integer> totalCapacity = new ArrayList<>();
used.add(1);
used.add(2);
used.add(3);
totalCapacity.add(3);
totalCapacity.add(3);
totalCapacity.add(3);
System.out.println(minPartitions(used,totalCapacity));
}
public static int minPartitions(List<Integer> used, List<Integer> totalCapacity) {
// Write your code here
int sizeOfUsedPartion = used.size();
int sizeOfMemoryUsed = totalCapacity.size();
List<Integer> newMemory = new ArrayList<>();
while(sizeOfMemoryUsed != 0)
{
for(int i=0; i<sizeOfUsedPartion;i++)
{
for(int j=0; j<i;j++)
{
if((used.get(i)+used.get(j)) <= totalCapacity.get(i))
{
newMemory.add((used.get(i)+used.get(j)));
break;
}
}
}
}
return newMemory.size();
}
}
//You can use greedy approach. The below code is in c++.
#include<bits/stdc++.h>
using namespace std;
int minParts(vector<int>usedSpace,vector<int>totalSpace){
int q;
q=totalSpace.size();
sort(usedSpace.begin(),usedSpace.end());
sort(totalSpace.begin(),totalSpace.end());
int used=accumulate(usedSpace.begin(),usedSpace.end(),0);
int min=0;
for(int i=q-1;i>=0;i--){
if(used<=totalSpace[i]){
min=min+1;
break;
}
else{
used=used-totalSpace[i];
min=min+1;
}
}
return min;
}
int main(){
vector<int>usedSpace={3,2,1,3,1};
vector<int>totalSpace={3,5,3,5,5};
int m=minParts(usedSpace,totalSpace);
cout<<m;
return 0;
}
//modify the code to give user input
//I could not find a better approach

Determine whether or not there exist two elements in an array whose sum is exactly X?

Given an array A[] of N elements and a number x, check for pair in A[] with sum as x ?
Method 1 = Sorting which gives O(n lg n).
Method 2 = Using hash table which gives O(n) .
I am having a doubt in method 2, that what if chaining is used , then for every element we have to search in list for its complement , which can yield O(n^2) in worst case because of chaining .
I think it will work only when range of integers is given , so that we can have hashtable without chaining which gives O(n) . Am i right ?
You can try the following approach ->
hash all elements in A[], like (key, value) = (A[i],true)
for all elements in A[]:
if hash(x-A[i])=true: it exists
You are right about hashtable that O(n) is not the WORST CASE guaranteed complexity.
However, with a reasonable hash function, the worst case should rarely happen.
And of course, if a small enough upper bound is given on the range of numbers, you can just use normal array to do the trick.
O(N) solution which uses hashmap to maintain the element Vs its frequency. Frequency is maintained so as to make it work for duplicate array elements case.
public static boolean countDiffPairsUsingHashing(int[] nums, int target) {
if (nums != null && nums.length > 0) {
HashMap<Integer, Integer> numVsFreq = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
numVsFreq.put(nums[i], numVsFreq.getOrDefault(nums[i], 0) + 1);
}
for (int i = 0; i < nums.length; i++) {
int diff = target - nums[i];
numVsFreq.put(nums[i], numVsFreq.get(nums[i]) - 1);
if (numVsFreq.get(diff) != null && numVsFreq.get(diff) > 0) {
return true;
}
numVsFreq.put(nums[i], numVsFreq.get(nums[i]) + 1);
}
}
return false;
}

Having trouble with Downheap Algorithm via array implementation

I am currently trying to sort my array of keys using the Down-heap algorithm. However, when I display my newly sorted array, new numbers appear and the order doesn't seem right. I cannot tell if something is wrong with my algorithm or if I'm not using the proper conditions for this sorting algorithm.
My job is to sort an array of 20 keys.
The Code:
/* Downheap sorting algorithm */
for(i=0; i<20; i++)
{
j = i + 1;
/* If parent is less than both children */
if(key[j] < key[2*j] && key[j] < key[(2*j)+1])
{
/* Check which child is smallest */
if(key[2*j] < key[(2*j)+1])
{
/* Parent is assigned smallest node */
swap(&key[j],&key[2*j]);
}
else{swap(&key[j],&key[(2*j)+1]);}
}
/* If parent is less than left child */
else if(key[j] < key[2*j])
{
swap(&key[j],&key[2*j]);
}
/* If parent is less than right child */
else if(key[j] < key[(2*j)+1])
{
swap(&key[j],&key[(2*j)+1]);
}
}
The Swap Function:
void swap(int *parent, int *child)
{
int temp;
temp = *child;
*child = *parent;
*parent = temp;
}
Array of keys before sorting:
54,90,137,260,185,65,208,139,114,176,186,77,137,139,178,57,203,110,80,127
Array of keys after sorting once:
54,137,185,260,114,77,208,178,110,176,186,65,137,139,139,64,203,90,84,127
64 was not there before. Where is 57? 80 has disappeared and where did 84 come from?
Any help would be much appreciated!
If you have an array of 20 numbers they will usually be key[0]..key[19], and with a heap you will need to consider the possibility that one or more of the children of a heap element do not exist because their array positions would be off the edge of the array. With heap numbers 0..19 then the children of element i would be at 2i+1 and 2i+2, so 0 has children 1 and 2, 1 has children 3 and 4... 8 has children 17 and 18, but 9 has only one child at 19 and 10 has no children at all.
Are you expecting Downheap to do all of the work of sorting? Normally, as explained at http://en.wikipedia.org/wiki/Heapsort, Downheap is part but not all of Heapsort.
By "DownHeap" i am asuming you mean Min-Heap
Algo for min heap :
public void insert(Comparable x)
{
if(size == heap.length - 1) doubleSize();
//Insert a new item to the end of the array
int pos = ++size;
//Percolate up
for(; pos > 1 && x.compareTo(heap[pos/2]) < 0; pos = pos/2 )
heap[pos] = heap[pos/2];
heap[pos] = x;
}'
Check This Link To understand min heapmin heap

Find maximum occuring integer (Mode) in an unsorted array

How to find the integer occurring maximum number of times (mode) in an unsorted array of integers?
One O(nlogn) approach I could think of is to sort. Is there any other better approach?
Here's a basic outline of what you will be doing:
First sort the array - O(n logn) incase of a merge sort
Declare Count=1, Max_Count=1, Max_Value=arr[0]
Iterate through array starting at index 1
Compare each element with Previous element. Update the count, Max_Count if they are equal, else reset count back to 1
return Max_Count, Max_value
Time Complexity : O(n logn)+ O(n)
Space Complexity : InPlace , no hash table or hash map is required.
Here is the code:
public void Max_Occurrence(int[] arr)
{
int count=1;
int max_count =1;
int max_value = arr[0];
for(int i=1; i<arr.length ; i++)
{
if(arr[i-1] == arr[i])
{
count++;
if(max_count<count)
{
max_count = count;
max_value = arr[i];
}
}
else
{
count = 1;//changing from count++. As per the steps mentioned above it should be reset to count = 1. Suggested by an anonymous user
}
}
System.out.println("Result:"+max_value+" has occured "+max_count+"of times");
}
I think you want to find out element that has most occurences in the array -
if you don't care about memory, traverse the array once, increase count of each element in the hashtable. Then find the one with highest count. You'd need one traverse of array and one of the hashtable.
so in pseudocode:
hashtable hash;
foreach(element in array){
if(!hash.contains(element))
hash[element] = 1;
else
hash[element]++;
}
int max = 0;
max_element;
foreach(element in hash)
if(hash[element] > max)
{
max_element = element;
max = hash[element];
}
//max_element contains the maximum occuring one.
If you are using Linq you can do this
IEnumerable.Max();
You can use a hashtable with "the number in array" as key and "occurrences" as values.
Sample code be like this:
hashtable h;
for every entry in array
search hashtable
if present, increment num_occurrences
else, create new entry
Iterate over all the entries in hashtable and return one
with max num_occurrences
As searching in hash is considered O(1), the overall complexity will be O(n).
A special case of this problem is when the numbers in array are in a given range, in that case take another array of ints with size of maximum value in the original array,and use the index of new array as key and the number stored in this array as count of occurrences.
Return the index of the largest value in this array.
Try this.
class max_frequency
{
private int a[]=new int[20];
public void accept(int a1[])
{
a=a1;
}
public void sort()
{
int i,j,t;
for(i=0;i<20;i++)
{
for(j=i+1;j<20;j++)
{
if(a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
int count=1;
int max_count=1;
int max_value=0;
for(i=1;i<a.length;i++)
{
if(a[i-1]==a[i])
{
count++;
if(max_count<count)
{
max_count=count;
max_value=a[i];
}
}
else
{
count=1;
}
}
System.out.println("Result : "+max_value+ " has occured "+max_count+ " times");
}
}

Resources