#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// Node structure for binary tree
typedef struct Node {
int data;
struct Node* left;
struct Node* right;
} Node;
// Queue node for BFS storing tree node and horizontal distance
typedef struct QNode {
Node* treeNode;
int hd;
struct QNode* next;
} QNode;
// Queue structure
typedef struct Queue {
QNode *front, *rear;
} Queue;
// Create new tree node
Node* newNode(int data) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
// Create new queue node
QNode* newQNode(Node* treeNode, int hd) {
QNode* qnode = (QNode*)malloc(sizeof(QNode));
qnode->treeNode = treeNode;
qnode->hd = hd;
qnode->next = NULL;
return qnode;
}
// Initialize queue
Queue* createQueue() {
Queue* q = (Queue*)malloc(sizeof(Queue));
q->front = q->rear = NULL;
return q;
}
// Enqueue operation
void enqueue(Queue* q, Node* treeNode, int hd) {
QNode* temp = newQNode(treeNode, hd);
if (q->rear == NULL) {
q->front = q->rear = temp;
return;
}
q->rear->next = temp;
q->rear = temp;
}
// Dequeue operation
QNode* dequeue(Queue* q) {
if (q->front == NULL) return NULL;
QNode* temp = q->front;
q->front = q->front->next;
if (q->front == NULL) q->rear = NULL;
return temp;
}
// Check if queue is empty
int isEmpty(Queue* q) {
return q->front == NULL;
}
// Map structure for horizontal distance to node data
typedef struct MapNode {
int hd;
int data;
struct MapNode* next;
} MapNode;
// Insert into map only if hd not present
void insertMap(MapNode** head, int hd, int data) {
MapNode* curr = *head;
while (curr != NULL) {
if (curr->hd == hd) return; // already recorded
curr = curr->next;
}
MapNode* new_map_node = (MapNode*)malloc(sizeof(MapNode));
new_map_node->hd = hd;
new_map_node->data = data;
new_map_node->next = *head;
*head = new_map_node;
}
// Find min and max hd in map
void findMinMax(MapNode* head, int* min_hd, int* max_hd) {
*min_hd = INT_MAX;
*max_hd = INT_MIN;
MapNode* curr = head;
while (curr != NULL) {
if (curr->hd < *min_hd) *min_hd = curr->hd;
if (curr->hd > *max_hd) *max_hd = curr->hd;
curr = curr->next;
}
}
// Get data for given hd
int getData(MapNode* head, int hd) {
MapNode* curr = head;
while (curr != NULL) {
if (curr->hd == hd) return curr->data;
curr = curr->next;
}
return -1; // not found
}
// Print top view of binary tree
void topView(Node* root) {
if (root == NULL) return;
Queue* q = createQueue();
MapNode* hd_map = NULL;
enqueue(q, root, 0);
while (!isEmpty(q)) {
QNode* temp = dequeue(q);
Node* curr_node = temp->treeNode;
int hd = temp->hd;
free(temp);
// Record first node at this horizontal distance
insertMap(&hd_map, hd, curr_node->data);
if (curr_node->left != NULL) enqueue(q, curr_node->left, hd - 1);
if (curr_node->right != NULL) enqueue(q, curr_node->right, hd + 1);
}
int min_hd, max_hd;
findMinMax(hd_map, &min_hd, &max_hd);
for (int i = min_hd; i <= max_hd; i++) {
int val = getData(hd_map, i);
if (val != -1) {
printf("%d", val);
if (i < max_hd) printf(" -> ");
}
}
printf("\n");
}
int main() {
// Construct tree from dry run
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->right = newNode(4);
root->right->right = newNode(5);
topView(root);
return 0;
}
Start BFS from root with horizontal distance 0
QNode* temp = dequeue(q);
Remove front node from queue to process
insertMap(&hd_map, hd, curr_node->data);
Record first node encountered at this horizontal distance
if (curr_node->left != NULL) enqueue(q, curr_node->left, hd - 1);
Add left child with hd one less
if (curr_node->right != NULL) enqueue(q, curr_node->right, hd + 1);
Add right child with hd one more
findMinMax(hd_map, &min_hd, &max_hd);
Find range of horizontal distances recorded
for (int i = min_hd; i <= max_hd; i++) { int val = getData(hd_map, i); ... }
Print nodes in order from leftmost to rightmost horizontal distance