Balancing AVL tree height/balance factor error - c

Alright so there is a lot of code here, but I thought it was best in case something wasn't immediately evident in my logic.
My issue starts with the height, and my calculated balancing factor. I have looked up a countless amount of AVL-tree algorithms, and done a lot of rough work on paper to try to figure out the best way to tackle the balancing aspect of this beast of a tree. Here is what I've gotton:
typedef struct node {
char* key;
struct node *left;
struct node *right;
int height;
int frequency;
}node;
int max(int a, int b)
{
if(a > b)
{
return a;
}
else
return b;
}
// A utility function to get height of the tree
int height(node* N)
{
if(N==NULL)
return -1;
return N->height;
}
// A utility function to get maximum of two integers
int avlHeight(node* N) {
if(N == NULL)
return -1;
else
return max(height(N->left), height(N->right))+1;
}
node *rightRotate(node *y) //preform a right AVL rotation
{
node *x = y->left;
node *T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right))+1;
x->height = max(height(x->left), height(x->right))+1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
node *leftRotate(node *x) //perform a left AVL rotation
{
node *y = x->right;
node *T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right))+1;
y->height = max(height(y->left), height(y->right))+1;
// Return new root
return y;
}
// Get Balance factor of node N
int getBalance(node *N)//get the balance factor
{
if (N == NULL)
return -1;
return height(N->left) - height(N->right);
}
node* insert(node* node, char* key)//function to insert new nodes to the tree
{
if (node == NULL)
return (newNode(key));
// printf("%s",key);
if(strcmp(node->key, key)==0)
{
node->frequency = node->frequency+1;
return node;
}
if (strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* 2. Update height of this ancestor node */
node->height = max(height(node->left), height(node->right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
printf("%d\n",balance);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && strcmp(key, node->left->key)<0) {
return rightRotate(node);
}
// Right Right Case
if (balance < -1 && strcmp(key, node->right->key)>0)
return leftRotate(node);
// Left Right Case
if (balance > 1 && strcmp(key, node->left->key)>0) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && strcmp(key, node->right->key)<0) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
I̶ ̶d̶o̶ ̶n̶o̶t̶ ̶g̶e̶t̶ ̶a̶n̶y̶ ̶s̶e̶g̶-̶f̶a̶u̶l̶t̶s̶,̶ ̶e̶r̶r̶o̶r̶s̶,̶ ̶o̶r̶ ̶w̶a̶r̶n̶i̶n̶g̶s̶.̶ The program segfaults when the balance factor is 2. I am parsing roughly 44k lines of keys into this tree, and any multiples are being added to the structs frequency counter. The only thing that is not correct with my tree is that the frequency is off by 1-3 elements for any given node, and the heights are not what they should be for all elements.
I was pretty sure when I was debugging it had to do with my balancing algorithm, because for one my heights were completely off (got as high as 7 I believe) and about 70% of my nodes had the correct amount of counts (frequency).
My big question: What is wrong with my balancing logic and/or rotation logic?
Is my entire code wrong, or am I at least on the right track?
**after updating code
for some god forsaken reason when I take out the node I segfault at, the entire program works, but gives me the wrong frequencies still :/
So quite literally 1 element/node makes this segfault, yet it is still wrong...
example input->
wrn69 flr830 flr662 flr830 flr830
flr231 flr2166 flr1854 wrn69 wrn69
flr231 flr2166
wrn69
flr830

Related

How to solve this Depth first search problem?

So I need to do a depth first search traversal of a given graph, however if a node in the graph has multiple adjacent neighbours, I need to choose the node with the lowest value to go to. So I implemented the following recursive depth first search function:
void DFS(struct Graph *graph, int vertex) {
struct node *adjList = graph->adjLists[vertex];
struct node *temp = adjList;
graph->visited[vertex] = 1;
printf("Visited %d \n", vertex);
int neighbouring_nodes[graph->numVertices];
while (temp != NULL) {
int count = 0;
struct node *temp_cpy = temp;
while (temp_cpy != NULL) {
neighbouring_nodes[count] = temp_cpy->vertex;
count++;
temp_cpy = temp_cpy->next;
}
int smallest_node = neighbouring_nodes[0];
for (int i = 0; i < count; i++) {
if (neighbouring_nodes[i] < smallest_node) {
smallest_node = neighbouring_nodes[i];
}
}
if (graph->visited[smallest_node] == 0) {
DFS(graph, smallest_node);
} else if (graph->visited[smallest_node] == 1 && count == 1) {
//if the node is visited but is it the only neighbour
DFS(graph, smallest_node);
}
temp = temp->next;
}
}
But when I run my program, it results in an infinite loop. I think I know why I am getting an infinite loop, it might be because there is never a return condition, so the recursive function just keeps running?
Is this type of depth first search possible with a recursive function? If yes, where am I going wrong? If no, how would I do it iteratively?
Help would be much appreciated.
Below is my full program without the DFS function:
// DFS algorithm in C
#include <stdio.h>
#include <stdlib.h>
struct node {
int vertex;
struct node *next;
};
struct node *createNode(int v);
struct Graph {
int numVertices;
int *visited;
struct node **adjLists;
};
// Create a node
struct node *createNode(int v) {
struct node *newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// Create graph
struct Graph *createGraph(int vertices) {
struct Graph *graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;
graph->adjLists = malloc(vertices * sizeof(struct node*));
graph->visited = malloc(vertices * sizeof(int));
int i;
for (i = 0; i < vertices; i++) {
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
// Add edge
void addEdge(struct Graph *graph, int src, int dest) {
// Add edge from src to dest
struct node *newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;
// Add edge from dest to src
newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}
// Print the graph
void printGraph(struct Graph *graph) {
int v;
for (v = 0; v < graph->numVertices; v++) {
struct node *temp = graph->adjLists[v];
printf("\n Adjacency list of vertex %d\n ", v);
while (temp) {
printf("%d -> ", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}
int main() {
struct Graph *graph = createGraph(4);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 2, 3);
printGraph(graph);
DFS(graph, 2);
return 0;
}
"if a node in the graph has multiple adjacent neighbours, I need to choose the node with the lowest value to go to."
I assume the 'value' of a node is an attribute of the node object?
Most implementations of DFS will first look at the node with the lowest index in the data structure containing the node objects. So, if you first sort the nodes in your data structure into ascending value order, then the DFS will do what you want without needing to change the DFS code.
Here is what I came up with:
void DFS(struct Graph* graph, int vertex) {
struct node* temp = graph->adjLists[vertex];
graph->visited[vertex] = 1;
printf("Visited %d \n", vertex);
int neighbouring_nodes[graph->numVertices];
int count = 0;
while(temp != NULL) {
neighbouring_nodes[count] = temp->vertex;
count++;
temp = temp->next;
}
int smallest_node = neighbouring_nodes[0];
// Need to search (at most) in every neighbouring node
for (int i = 0; i < count; i++) {
// Go through all nodes in neighbouring_nodes array in order
// to find the smallest unvisited one, if it exists
for (int j = 0; j < count; j++){
// if current smallest_node has already been visited and
// neighbouring_nodes[j] is unvisited, assign it to smallest_node
if (graph->visited[smallest_node] == 1 && graph->visited[neighbouring_nodes[j]] == 0){
smallest_node = neighbouring_nodes[j];
}
// if neighbouring_nodes[j] is smaller than smallest_node,
// assign it to smallest_node
if (graph->visited[neighbouring_nodes[j]] == 0 && neighbouring_nodes[j] < smallest_node){
smallest_node = neighbouring_nodes[j];
}
}
if (graph->visited[smallest_node] == 0){
// calls DFS on the smallest unvisited neighboring node, if it exists
DFS(graph, smallest_node);
}else{
// otherwise (all neighboring nodes already visited)
// return control to the caller function
return;
}
}
}
I'm not 100% sure I understood what you wanted to do with the while (temp != NULL) and while (temp_cpy != NULL) loops but couldn't really figure out a way to use this approach especially in your particular case in which you want to visit the neighboring nodes in ascending order.
Let's assume a simple graph like 6->0->1, calling DFS(g, 0) will get temp to point to 6->1->NULL (could be also 1->6->NULL, depending on how you construct the graph), then smallest_node will be 1 and therefore the node 1 will be visited and the temp = temp->next will "assign" 1->NULL to temp. Back to the beginning of the loop, now temp_cpy will "be equal" to temp, hence 1->NULL. The node 6 is not on the list anymore even if it was not visited, on the other hand the already visited node 1 is still there. Also count is now equal to 1 therefore the condition (graph->visited[smallest_node] == 1 && count == 1) is met and DFS(g, 1) is called, which should not since node 1 was already visited. The infinite loop arises from this, since the previous condition is always met when temp has one (already visited) element left ([some value]->NULL). Once you reach that point you always call DFS(g, [some value]) and this will never give back control, since before reaching the temp = temp->next statement (which should assign NULL to temp , hence ending the while loop), DFS(g, [some other value]) is again called, which at some point will again call DFS(g, [some value]), and so forth.
As mentioned, one problem your original code has is that you call the DFS function also for an already visited vertex, and this should never be the case. When you encounter an already visited neighboring vertex, you want either to check the next or, if there are no unvisited neighboring vertices left, to give back control to the caller function. Therefore the last if else statement should not be there. The second problem is that smallest_node is selected in the wrong way. This is because temp_cpy, as explained above, is not constructed in such a way that it necessarily contains all unvisited neighboring nodes and also because you're actually looking for the smallest element in this list, regardless if it has already been visited or not (again because of the assumption that temp_cpy contains only all unvisited nodes). In fact you should be looking for the "smallest unvisited node" rather than the "smallest node".
In my code I go through all neighboring nodes with two for loops, find the smallest unvisited one and call DFS(g, [smallest unvisited node]) and once there are no unvisited neighbors left, return control back to the caller function.
I Hope this is somewhat understandable and I also hope I'm not missing something about what you had in mind with your implementation, in which case I would be very much interested in some explanations!
Here is a simpler version of the DFS in which neighboring nodes are checked and eventually visited in the order they're presented in the adjList. In this case I think the while (temp != NULL)/temp = temp->next approach makes sense:
void DFS(struct Graph *graph, int vertex) {
struct node *temp = graph->adjLists[vertex];
graph->visited[vertex] = 1;
printf("Visited %d \n", vertex);
// for vertex search in every neighboring node
while (temp != NULL) {
// if neighboring vertex temp->vertex not visited, then search there
if (graph->visited[temp->vertex] == 0) {
DFS(graph, temp->vertex);
// if already visited, go to the next vertex on the neighbors list
}else{
temp = temp->next;
}
}
// when searched in all neighboring vertexes return control to caller
return;
}

kd-tree iterative non-stack based insertion

Im looking for iterative non-stack based (due to memory constraints, and minimal refactoring) kd-tree insertion only.
I have an entire kd-tree library working in C, functions (insert ,read, update, delete, knn search, rebalancing) I started to replace all recursive functions with iterative ones.
However, I noticed that my insertion was not working for some test data. Meaning actually the search could not find the inserted nodes when using iterative implementation but all data was found when using recursive implementation, , therefore, the bug is in iterative insert version.
node structure:
typedef struct kd_tree_node
{
struct kd_tree_node* left;
struct kd_tree_node* right;
struct kd_tree_node* parent;
float* dataset;
float distance_to_neighbor;
} kd_tree_node;
Below is an iterative insertion (i included parts directly related. No rebalacing logic, etc...):
void
kd_tree_add_record(kd_tree_node* root, const float data [], int depth,
const int k_dimensions,
const int copying, const float rebuild_threshold) {
/*rebalancing logic is NOT relevant, which I have NOT include, we can just build inefficient tree*/
/* is root empty? */
if (is_empty_node(root, k_dimensions)) {
root = kd_tree_new_node(data, k_dimensions, copying);
/*was the root set before*/
if (is_empty_node(kd_tree_get_root(), k_dimensions)) {
kd_tree_set_root(root);
}
} else {
/*iteratively insert new node*/
current = kd_tree_get_root();
/*while current is NOT null*/
while (!is_empty_node(current, k_dimensions)) {
parent = current;
/* Calculate current dimension (cd) of comparison */
cd = depth % k_dimensions;
/*determine current dimension/*/
/*by using modula operator we can cycle through all dimensions */
/* and decide the left or right subtree*/
median = kd_tree_get_column_median(cd);
//printf("kd_tree_add_record.(), median=%f\n",median);
if (data[cd] < median) {
current = current->left;
} else {
current = current->right;
}
depth++;
}//end while
/*should be inserted left or right of the parent*/
int insert_left = 1;
depth = 0;
if (!is_empty_node(parent,k_dimensions)) {
int c = 0;
for (; c < k_dimensions; c++) {
cd = depth % k_dimensions;
median = kd_tree_get_column_median(cd);
if (parent->dataset[cd] < median) {
} else {
insert_left = 0;
break;
}
depth++;
}
if (insert_left)
{
parent->left = kd_tree_new_node(data, k_dimensions, copying);
}
else
{
parent->right = kd_tree_new_node(data, k_dimensions, copying);
}
}
}//end else
}
I based my iterative kd-tree insert above code, by attempting to follow the iterative binary tree insert C++ code from: (https://www.techiedelight.com/insertion-in-bst/) which can be tested online, see below(note this not my code and its provided as reference):
void insertIterative(Node*& root, int key)
{
// start with root node
Node *curr = root;
// pointer to store parent node of current node
Node *parent = nullptr;
// if tree is empty, create a new node and set root
if (root == nullptr)
{
root = newNode(key);
return;
}
// traverse the tree and find parent node of key
while (curr != nullptr)
{
// update parent node as current node
parent = curr;
// if given key is less than the current node, go to left subtree
// else go to right subtree
if (key < curr->data)
curr = curr->left;
else
curr = curr->right;
}
// construct a new node and assign to appropriate parent pointer
if (key < parent->data)
parent->left = newNode(key);
else
parent->right = newNode(key);
}
Here is my previous kd-tree recursive insertion version, which works:
kd_tree_node *
kd_tree_add_record(kd_tree_node * root,
const float data[], int depth,
const int k_dimensions,
const int copying,
const float rebuild_threshold) {
float median = 0.0;
/* Tree is empty? */
if (NULL == root || NULL == root -> dataset || is_empty_node(root, k_dimensions)) {
root = kd_tree_new_node(data, k_dimensions, copying);
//update the root globally
if (kd_tree_get_root() == NULL) {
kd_tree_set_root(root);
}
} else {
/* Calculate current dimension (cd) of comparison */
size_t cd = depth % k_dimensions;
/*determine current dimension/*/
/*by using modula operator we can cycle through all dimensions */
/* and decide the left or right subtree*/
median = kd_tree_get_column_median(cd);
if (data[cd] < median) {
root -> left = kd_tree_add_record(root -> left, data, depth + 1,
k_dimensions,
copying, rebuild_threshold);
} else {
root -> right = kd_tree_add_record(root -> right, data, depth + 1,
k_dimensions,
copying, rebuild_threshold);
}
} //end else
return root;
}
current test results:
-53.148998,0.000000,9.000000 Found
7.999700,0.069812,8.000000 Found
7.998780,0.139619,8.000000 Found
7.997260,0.209416,8.000000 Not Found!
7.995130,0.279196,8.000000 Not Found!
7.992390,0.348955,8.000000 Not Found!
8.987670,0.471024,9.000000 Found
8.983210,0.549437,9.000000 Found
7.980510,0.558052,8.000000 Not Found!
3.000000,3.000000,3.000000 Found
4.000000,4.000000,4.000000 Found
5.000000,5.000000,5.000000 Found!
100.000000,100.000000,100.000000 Found
How can I extend the iterative non-stack binary insert algorithm to kd-trees?
Really appreciated!

C- method find average distance from root to leaves

How find average distance from root to all leaves in a binary tree
Dis­tance means num­ber of edges between the nodes.
The method get the root.
I think add new fields in node.
My code in C:
// A Binary Tree Node
struct Node
{
int data;
Node *left, *right;
};
int findDistance(Node *root)
{
// Base case
if (root == NULL)
return -1;
// Initialize distance
int dist = -1;
if ((root->data != NULL) ||
(dist = findDistance(root->left)) >= 0 + (dist = findDistance(root->right)) >= 0) /2
return dist + 1;
return dist;
}
I expect the following would work, but I have not tested it.
typedef struct
{
int Number; // Number of nodes in tree.
int TotalDepths; // Total of depth of each node.
} NAndTotal;
static NAndTotal FindNumberAndTotalDepth(Node *Root)
{
if (Root == NULL)
return (NAndTotal) { 0, 0 }; // No nodes in empty tree.
// Start an NAndTotal with information about the root node.
NAndTotal A = { 1, 0 }; // Root is 1 node at depth 0.
// Add the left subtree.
NAndTotal B = FindNumberAndTotalDepth(Root->left);
A.Number += B.Number; // Including left subtree adds its nodes.
A.TotalDepth += B.TotalDepth + B.Number; Each of its nodes become one deeper when placed under this node.
// Add the right subtree.
B = FindNumberAndTotalDepth(Root->right);
A.Number += B.Number; // Including right subtree adds its nodes.
A.TotalDepth += B.TotalDepth + B.Number; Each of its nodes become one deeper when placed under this node.
return A;
}
double FindAverage(Node *Root)
{
NAndTotal NT = FindNumberAndTotalDepth(Root);
return (double) NT.TotalDepths / NT.Number;
}

Executable Crashes When Function is Run

I am creating an AVL for an assignment, but when ever I call the rotate right and rotate left functions the executable crashes with no error message. I think it might be due to a NULL pointer exception but I'm not sure.
Here is my code for the rotations:
TNODE *rotate_right(TNODE *y){
TNODE *x=y->left;
TNODE *t2=x->right;
x->right=y;
y->left=t2;
y->height =max(height(y->left),height(y->right))+1;
x->height=max(height(x->left),height(x->right))+1;
}
TNODE *rotate_left(TNODE *x){
TNODE *y=x->right;
TNODE *t2=y->left;
y->left=x;
x->right=t2;
y->height =max(height(y->left),height(y->right))+1;
x->height=max(height(x->left),height(x->right))+1;
}
And here is the insert function I call them in:
void insert(TNODE **rootp, char *name, float score){
TNODE *np = (TNODE *) malloc(sizeof(TNODE));
if (np == NULL) return;
strcpy(np->data.name, name);
np->data.score = score;
np->height = 1;
np->left = NULL;
np->right = NULL;
// 1. Perform the normal BST insertion
if (*rootp == NULL) {
*rootp = np;
return;
}
TNODE *root = *rootp;
if (strcmp(name, root->data.name) < 0 ){
insert(&root->left, name, score);
}
else if (strcmp(name, root->data.name) > 0 ){
insert(&root->right, name, score);
}
else return ;
// 2. update height of this root node
// add your code here
root->height=height(root);
// STEP 3: get the balance factor of this root node
// add your code here
int balance=balance_factor(root);
// STEP 4: re-balance if not balanced
// add your code here
if(balance>1&&balance_factor(root->left)>=0){
rotate_right(root);
}
else if(balance>1&&balance_factor(root->left)<0){
rotate_left(root->left);
rotate_right(root);
}
else if(balance<-1&&balance_factor(root->right)>=0){
rotate_left(root);
}
else if(balance<-1&&balance_factor(root->right)<0){
rotate_right(root->right);
rotate_left(root);
}
}
The code runs fine if I comment out the last part where I have to rotate it so I'm quite sure the problem is there. Thanks in advance for any help.

Difficulty Constructing Binary Tree from Array

I am trying to build a binary tree from an unsorted float array for an assignment, but I cannot quite figure it out. My goal is to send the unsorted array xdata of size ndata to the function build_tree(), which creates a new node using the function create_node(). In the case that the array size is greater than 1, it will call the function paritition_data() (which works fine, but I've placed it at the bottom of the question for reference), which will swap the order of array values so that all values less than mid fall on its left, and greater values to its right. The function returns nleft, the number of values on the left of mid. I then want to recursively call partition_data() to create new left and right child nodes. I think it is at this step that my program seems to fail, and despite it compiling, the program seems to recursively call partition_data() infinitely, and I'm not sure why. I appreciate any help.
typedef struct treenode_struct {
int n;
float data;
struct treenode_struct *left, *right;
} treenode;
treenode *create_node( ) {
treenode *node;
node = malloc(sizeof(treenode));
if (node == NULL) {
printf("Allocate Failed");
exit(-1);
}
node->n = 0;
node->right = NULL;
node->left = NULL;
tree_nodes++;
return node;
}
treenode *build_tree( float xdata[], int ndata, float xmin, float xmax ) {
treenode *node;
int nleft;
float mid = (xmin+xmax)/2.;
node = create_node();
node->n = ndata;
if (ndata == 1) { // Add code for this case
node->data = xdata[0];
node->left = NULL;
node->right = NULL;
return node;
}
if (ndata == 0){
printf("Allocate failed\n");
exit(-1);
}
// More than one data point: use partition function
if (ndata > 1) {
nleft = partition_data(xdata,ndata,mid);
int nright = ndata-nleft;
// Add code to make a left child
if(nleft != 0){
node->left=build_tree(xdata,nleft,xmin,xdata[nleft-1]);
}
else{
node->left = NULL;
}
// Add code to make a right child
if(nright != 0){
node->right=build_tree(xdata,nright,xdata[nleft],xmax);
}
else{
node->right = NULL;
}
return node;
}
}
int tree_nodes;
int main() {
const int ndata = 16;
float xdata[] = { 0.963, 0.003, 0.0251, 0.353, 0.667, 0.838, 0.335, 0.915,
0.796, 0.833, 0.345, 0.871, 0.089, 0.888, 0.701, 0.735 };
int i;
float xmiddle = 0.5;
printf("Input data:\n");
for (i=0;i<ndata;i++) printf("%f ",xdata[i]);
printf("\n");
treenode *tree_root;
float tree_xmin, tree_xmax;
tree_nodes = 0;
tree_xmin = 0;
tree_xmax = 1;
tree_root = build_tree( xdata, ndata, tree_xmin, tree_xmax );
printf("Tree Built: nodes %d\n",tree_nodes);
printf("Tree Ordered data:\n");
for (i=0;i<ndata;i++) printf("%f ",xdata[i]);
printf("\n\n");
}
Here is partition_data():
int partition_data( float xdata[], int ndata, float xmiddle ) {
// Your code goes here
int left = 0;
int right = ndata-1;
float temp;
while(left < ndata){ //left loop
if(xdata[left] < xmiddle){
if(left == right){
return left+1;
break;
}//DONE
left = left + 1;
}
else{
while(right<ndata){ //right loop, search for swappable Xright
if(xdata[right] >= xmiddle){//X[right] is greater than/equal to xmiddle
if(left == right){
return left;
break;
}
right=right-1;
}
else{ //found X[right] to swap
temp = xdata[left];
xdata[left] = xdata[right];//swap
xdata[right]=temp;
right = right-1;
if(left == right) {
return left+1;
break;
}
left=left+1;
break;
}
break;
}
}
}
Your recursion problem is caused by the creation of your right node.
You create the right node with this code:
// Add code to make a right child
if(nright != 0){
node->right=build_tree(xdata,nright,xdata[nleft],xmax);
}
else{
node->right = NULL;
}
Now if you look at your build_tree function what you have is:
treenode *build_tree( float xdata[], int ndata, float xmin, float xmax )
Let's interprete it as:
create a tree from the array xdata[] where all elements are greater than xmin and less than xmax
Now don't see xdata[] as array xdata[] but see xdata as the pointer to the first element I have to process. This will (hopefully) help you understand it a little bit (and is actually what it is, it is just a pointer).
In your code to create the right node you use:
node->right=build_tree(xdata,nright,xdata[nleft],xmax);
but there you actually insert as right node the root of the tree that will be created by processing the data starting at the first element of your array. That's not the slice of the array you want. The slice you want to have in your right node is the right part of the array so the part that starts at index ndata-nright. So if you want to change the begin of an array, you just add the index to the pointer of the array. So in your case xdata + (ndata-nright) will represent an array that starts at element ndata-nright (or pointer to that element). So you should have:
node->right=build_tree(xdata + (ndata-nright),mid,xdata[nleft],xmax);
to create your right node!

Resources