Skip to content

Instantly share code, notes, and snippets.

@steinelu
Last active August 25, 2023 09:02
Show Gist options
  • Save steinelu/2153d9b195be1528072e694c697c0e13 to your computer and use it in GitHub Desktop.
Save steinelu/2153d9b195be1528072e694c697c0e13 to your computer and use it in GitHub Desktop.
Small C program that constructs a Cartesian tree from an array (and generates a Graphviz dot file from it)
#include <stdio.h>
#include <stdlib.h>
struct Node{
struct Node *parent;
struct Node *left;
struct Node *right;
int index;
int value;
};
typedef struct Node Node;
Node* createNode(Node* parent, Node* left, Node* right, int index, int value){
Node* node = malloc(sizeof(Node));
if (node == NULL)
printf("[Error] malloc returned NULL");
node->parent = parent;
node->left = left;
node->right = right;
node->index = index;
node->value = value;
return node;
}
Node* buildCartesianTree(int arr[], int len){
Node* cur = NULL;
for(int i = 0; i < len; i++){
Node* node = createNode(NULL, NULL, NULL, i, arr[i]);
if (cur == NULL){
cur = node;
continue;
}
//printf("(%d, %d)\n", cur->value, node->value);
if (cur->value < node->value){
cur->right = node;
node->parent = cur;
cur = node;
} else {
while (cur->value >= node->value){
if (cur->parent == NULL){
break;
}
cur = cur->parent;
}
if (cur->value >= node->value){
cur->parent = node;
node->left = cur;
cur = node;
} else {
node->parent = cur;
node->left = cur->right;
cur->right = node;
if(cur->right != NULL){
node->left->parent = node;
}
cur = node;
}
}
}
while(cur->parent != NULL){
cur = cur->parent;
}
return cur;
}
void printNode(Node* node, int depth){
if (node->left != NULL){
printNode(node->left, depth+1);
}
for(int i = 0; i < depth; i++){
printf(" ");
}
printf("[%d] %d\n", node->index, node->value);
if (node->right != NULL){
printNode(node->right, depth+1);
}
}
void print(Node* root){
printNode(root, 0);
}
void printDotNode(Node* node){
//printf("\t%d [label=\"%d @ [%d]\"];\n", node->index, node->value, node->index);
if (node->left != NULL){
printf("\t%d -> %d;\n", node->value, node->left->value);
printDotNode(node->left);
}
if (node->right != NULL){
printf("\t%d -> %d;\n", node->value, node->right->value);
printDotNode(node->right);
}
}
void printDot(Node* root){
printf("digraph G{\n");
printDotNode(root);
printf("}\n");
}
int main(){
int arr[] = {4, 5, 7, 3, 8, 9, 2, 6, 1, 0};
//int arr[] = {7, 8, 9, 10, 4, 12, 6, 11, 5, 3, 1, 2};
int len = sizeof(arr)/sizeof(int);
//printf("\\\\%d\n", len);
Node * root = buildCartesianTree(arr, len);
printDot(root);
//printf("hello world!\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment