ffind leaf nodes of the binary search tree - binary-search-tree

i was asked in a interview question that given the preorder traversal of a binary search tree , find out the leaf nodes without constructing the original tree. i know the property that binary search tree has to satisfy but i cannot find any relation into how can it be done utilising this property . only thing i can identify is that the first node in th preorder traversal will be always be root. also google search did not yield any result for this problem. i do not want the code just a simple hint to begin with would be sufficient.
EDIT: after trying out a lot i got this solution:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void fl(vector<int> &v, int lo, int hi){
if (lo>hi) return;
if (lo == hi) { cout<<"leaf ^^^^^^^ "<< v[hi]<<"\n"; return; }
int root = v[lo];
int i;
for(i = lo+1 ; i <= hi ; i++) if (v[i] > root) break;
fl(v, lo+1, i -1);
fl(v, i , hi);
}
int main(){
vector<int> v1 = {8, 3, 1, 6, 4, 7, 10, 14, 13};
vector<int> v2 = {27, 14, 10, 19, 35, 31, 42};
vector<int> v3 = {9,8,7,6,5,4,3,2,1};
fl(v3,0,v3.size()-1);
return 0;
}
any suggestions for improvement other than variable names will be very helpful

This program should print the leaf nodes from a preOrder of BST. The program is pretty self explanatory.
public static void findLeafs(int[] arr) {
if (arr == null || arr.length == 0)
return;
Stack<Integer> stack = new Stack<>();
for(int n = 1, c = 0; n < arr.length; n++, c++) {
if (arr[c] > arr[n]) {
stack.push(arr[c]);
} else {
boolean found = false;
while(!stack.isEmpty()) {
if (arr[n] > stack.peek()) {
stack.pop();
found = true;
} else
break;
}
if (found)
System.out.println(arr[c]);
}
}
System.out.println(arr[arr.length-1]);
}

def getLeafNodes(data):
if data:
root=data[0]
leafNodes=[]
process(data[1:],root,leafNodes)
return leafNodes
def process(data,root,leafNodes):
if data:
left=[]
right=[]
for i in range(len(data)):
if data[i]<root:
left.append(data[i])
if data[i]>root:
right.append(data[i])
if len(left)==0 and len(right)==0:
leafNodes.append(root)
return
if len(left)>0:
process(left[1:],left[0],leafNodes)
if len(right)>0:
process(right[1:],right[0],leafNodes)
else:
leafNodes.append(root)
#--Run--
print getLeafNodes([890,325,290,530,965])

Related

Pset5 (Speller) Weird Valgrind memory errors, no leaks

I have read other threads on pset5 Valgrind memory errors, but that didn't help me. I get 0 leaks, but this instead:
==1917== Conditional jump or move depends on uninitialised value(s)
Looks like you're trying to use a variable that might not have a value? Take a closer look at line 34 of dictionary.c.
The error refers to line 34 which is this: lower[i] = tolower(word[i]);
To supply context, the code below attempts to check if a word exists in the dictionary that has been uploaded to a hash table. I am attempting to convert the wanted word to lowercase because all the dictionary words are also lowercase and so that their hashes would be identical. The program successfully completes all tasks, but then stumbles upon these memory errors.
Any hints as to why Valgrind is mad at me? Thank you!
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
Below is the whole dictionary.c file:
// Implements a dictionary's functionality
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table 26^3
const unsigned int N = 17576;
// Hash table
node *table[N];
int count = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Modified hash function by Dan Berstein taken from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash = 5381;
int c;
while ((c = *word++))
{
hash = (((hash << 5) + hash) + c) % N; /* hash * 33 + c */
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *inptr = fopen(dictionary, "r");
if (dictionary == NULL)
{
printf("Could not load %s\n.", dictionary);
return false;
}
// Create a char array to temporarily hold the new word (r stands for read)
char r_word[N+1];
// Until the end of file
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
// Hash the node
int index = hash(new_node->word);
// Places the node at the right index
new_node->next = table[index];
table[index] = new_node;
}
fclose(inptr);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (&load == false)
{
return '0';
}
else
{
return count;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// Interates over the array
for (int i = 0; i < N; i++)
{
node *head = table[i];
while (head != NULL)
{
node *tmp = head;
head = head->next;
free(tmp);
}
}
return true;
}
This loop iterates through the maximum length of word-
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
Except if you look at how word is created-
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
Notice, the variable r_word, may not be exactly of length LENGTH + 1. So what you really have in word is N number of characters, where N is not necessarily LENGTH + 1, it could be less.
So looping over the entire 0 -> LENGTH + 1 becomes problematic for words that are shorter than LENGTH + 1. You're going over array slots that do not have a value, they have garbage values.
What's the solution? This is precisely why c strings have \0-
for (int i = 0; word[i] != '\0'; i++)
{
lower[i] = tolower(word[i]);
}
This will stop the loop as soon as the NULL character is reached, which, you must have already learnt, marks the end of a string - aka a char array.
There may still be more errors in your code. But for your particular question - reading out of bounds is the answer.

Preoder to BST construction

I am attempting to create a BST from an array of pre-order traversal. I wrote the following code, but can't figure out where am I making a mistake. The following code returns Nodes with values null. I am using the following approach:
10 8 4 5 14 12
I will partition it (after removing staring element):
8 4 5 and 14 12, (recursively).
public Node generateTree(int ar[], int low, int high) {
if (ar.length == 0 || low > high)
return null;
if (low == high)
return new Node(ar[low]);
int partitionPoint = findPartitionPoint(ar, low, high);
Node root = new Node(ar[low]);
if (partitionPoint != -1) {
root.left = generateTree(ar, low + 1, partitionPoint);
root.right = generateTree(ar, partitionPoint + 1, high);
} else {
root.left = generateTree(ar, low + 1, high);
}
return root;
}
private int findPartitionPoint(int ar[], int low, int high) {
if (high >= ar.length)
return -1;
for (int x = low; x <= high; x++) {
if (ar[x] > ar[low])
return x-1;
}
return -1;
}
I figured out the culprit. The issue was with Traversal function which I wrote separately. The Node function here takes int value, however, in Traversal function, I was printing its String value (my Node class has both String and Integer as keys). Such a silly mistake!
The code appears correct.

How to acquire skeletal joint data to text file from two kinect cameras in SkeletalViewer? (C++)

I am currently working on a project to use multiple kinect cameras to acquire x,y,z coordinates of skeletal data in SkeletalViewer. I have an idea to use the KinectID or index of different kinect cameras to extract the sets of skeletal joints data into 2 different text files. But I am not sure if I am doing right. Please help to take a look at the modification below, or I will appreciate all your kind advice on other method to solve this problem.
In SkeletalViewer.h, I modified as following:
public:
FILE* mp3DFile0;
FILE* mp3DFile1;
char mText[1024];
INuiSensor * m_pNuiSensor;
BSTR m_instanceId;
array SensorIndex;
In NuiImpl.cpp, I modified as following:
1) define array
ref class MyClass {
public:
int m_i;
};
array<MyClass^>^ arrSensor() {
int i;
array< MyClass^ >^ local = gcnew array< MyClass^ >(2);
for (i = 0; i < 2; i++) {
local[i] = gcnew MyClass;
local[i]->m_i = i;
}
return local;
}
2) create array to store sensor index to do for loop later
HRESULT CSkeletalViewerApp::Nui_Init( )
{
HRESULT hr;
bool result;
//create an array to store two file pointers
FILE* mp3DFile[] = { mp3DFile0, mp3DFile1 };
fopen_s(mp3DFile0, "D:/Kinect/KinectCam0.txt", "w+");
fopen_s(mp3DFile1, "D:/Kinect/KinectCam1.txt", "w+");
.
.
if ( !m_pNuiSensor )
{
hr = NuiCreateSensorByIndex(0, &m_pNuiSensor);
//I am not sure about how to utilize this index in this case
.
.
}
if (NuiGetSensorCount(&m_pNuiSensor) > 1)
{
array< MyClass^ >^ SensorIndex;
SensorIndex = arrSensor();
}
}
3) use for loop to store data to different text file using index
void CSkeletalViewerApp::Nui_DrawSkeleton( const NUI_SKELETON_DATA & skel, int windowWidth, int windowHeight )
{
int i;
int h;
for (h = 0; h < 2; h++)
{
//when index point to the current kinect
if (SensorIndex[h] == &m_pNuiSensor)
{
for (i = 0; i < NUI_SKELETON_POSITION_COUNT; i++)
{
m_Points[i] = SkeletonToScreen(skel.SkeletonPositions[i], windowWidth, windowHeight);
memset(mText, 0, 1024);
sprintf(mText, "(%0.3f,%0.3f,%0.3f)", skel.SkeletonPositions[i].x, skel.SkeletonPositions[i].y, skel.SkeletonPositions[i].z);
if (mp3DFile[h]) {
fputs((const char*)mText, mp3DFile[h]);
}
}
if (mp3DFile[h]) {
fputs("\n", mp3DFile[h]);
}
}
}
.
.
}
I am a newbie in this Kinect programming. Thank you very much for your help! :)

Whats wrong with my code? The backwards loop doesnt work (Option 2)

The option (2) crashes/overloads my coding software, it has the same code as option (1), does anybody know why its doing it and how to fix it?
#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
int length();
float mtof(int note);
int main() {
// do while the user hasnt pressed exit key (whatever)
int control[8] = {74, 71, 91, 93, 73, 72, 5, 84};
int index;
int mod;
float frequency;
int notes[8];
int response;
mod = aserveGetControl(1);
// ask backwards, forwards, exit
// SCALING
// (getControl(75) / ((127 - 0) / (1000 - 100))) + 100;
while(true) {
printf("Run Loop Forwards (1), Backwards (2), Exit (0)\n");
scanf("%d", &response);
if(response == 1) {
while(mod == 0) {
for(index = 0; index < 8; index++) {
notes[index] = aserveGetControl(control[index]);
frequency = mtof(notes[index]);
aserveOscillator(0, frequency, 1.0, 0);
aserveSleep(length());
printf("Slider Value:%5d\n", notes[index]);
mod = aserveGetControl(1);
}
}
} else if(response == 2) {
// here is the part where the code is exactly
// the same apart from the for loop which is
// meant to make the loop go backwards
while(mod == 0) {
for(index = 8; index > 0; index--) {
notes[index] = aserveGetControl(control[index]);
frequency = mtof(notes[index]);
aserveOscillator(0, frequency, 1.0, 0);
aserveSleep(length());
printf("Slider Value:%5d\n", notes[index]);
mod = aserveGetControl(1);
}
}
} else if(response == 0) {
return 0;
}
}
}
int length() {
return (aserveGetControl(75)/((127.0 - 0) / (1000 - 100))) + 100;
}
float mtof(int note) {
return 440 * pow(2, (note-69) / 12.0);
}
Your for loops aren't exactly the same.
The first option goes through { 0, 1, ..., 7 }
The second option goes through { 8, 7, ..., 1 }
Notice also that control[8] is undefined (0..7). So when it tries to reference this location the application runs into an error.
Change the second for loop to
for (index = 7; index >= 0; index--) {
...
}

Platform::Collections::Vector sorting

In Metro Style apps sometimes we use Platform::Collections::Vector to hold elements used in a ListView.
How to sort a Platform::Collections::Vector?
I'm aware there are plenty of structures in std that can be sorted but I was wondering if there was some method for Platform::Collections::Vector other than writing your own sort function.
Actually something like the below should also work:
auto vec = ref new Platform::Collections::Vector<T^>();
std::sort(begin(vec), end(vec));
I didn't find any suitable answer so I used this workaround.
It's a simple quicksort over a Platform::Collections::Vector
void swap (Platform::Collections::Vector<T^>^ vec, int pos1, int pos2)
{
T^ tmp = vec->GetAt(pos1);
vec->SetAt(pos1, vec->GetAt(pos2));
vec->SetAt(pos2,tmp);
}
int compare (T^ c1, T^ c2)
{
int c = wcscmp (c1->Title->Data(),c2->Title->Data());
return -c;
}
int PartitionVec (int left, int right,
Platform::Collections::Vector<T^>^ vec)
{
int i,j;
i = left;
for (int j = left + 1; j <= right; ++j)
{
if (compare (vec->GetAt(j),vec->GetAt(left)) > 0)
{
++i;
swap (vec,i,j);
}
}
swap (vec,left,i);
return i;
}
void QuickSortVec (Platform::Collections::Vector<T^>^ vec,
int start, int end)
{
if (end > start)
{
int pivot_point;
pivot_point = PartitionVec (start, end, vec);
QuickSortVec (vec,start,pivot_point - 1);
QuickSortVec (vec, pivot_point + 1, end);
}
}