View difference between Paste ID: CPbuFpKc and 4FqUdC6J
SHOW: | | - or go back to the newest paste.
1
#include<stdio.h>
2
#include<stdlib.h>
3
4
#define bool int
5
6
/* A binary tree node has data, pointer to left child
7
   and a pointer to right child */
8
struct node
9
{
10
   int data;
11
   struct node* left;
12
   struct node* right;
13
};
14
15
/*
16
 Original example code.
17
18
 Given a tree and a sum, return true if there is a path from the root
19
 down to a leaf, such that adding up all the values along the path
20
 equals the given sum.
21
22
 Strategy: subtract the node value from the sum when recurring down,
23
 and check to see if the sum is 0 when you run out of tree.
24
*/
25
bool hasPathSum_original(struct node* node, int sum)
26
{
27
  /* return true if we run out of tree and sum==0 */
28
  if (node == NULL)
29
  {
30
     return (sum == 0);
31
  }
32
33
  else
34
  {
35
    bool ans = 0;
36
37
    /* otherwise check both subtrees */
38
    int subSum = sum - node->data;
39
40
    /* If we reach a leaf node and sum becomes 0 then return true*/
41
    if ( subSum == 0 && node->left == NULL && node->right == NULL )
42
      return 1;
43
44
    if(node->left)
45
      ans = ans || hasPathSum_original(node->left, subSum);
46
    if(node->right)
47
      ans = ans || hasPathSum_original(node->right, subSum);
48
49
    return ans;
50
  }
51
}
52
53
/*
54-
Here is the original example without optimization. You'll see that the algorithm is much cleaner now. You had a bug in your rewrite as it answered the question "Is there A path with the given sum?" when you had nodes which had a left node without a right one (or vice versa).
54+
Here is the original example without optimization. You'll see that the algorithm is much cleaner now.
55
Note that this will short-circuit the calls in the line with the return statement.
56
*/
57
bool hasPathSum_revised(struct node* node, int sum)
58
{
59
  /* return true if we run out of tree and sum==0 */
60
  if (node == NULL)
61
     return (sum == 0);
62
63
  /* otherwise check both subtrees */
64
  int subSum = sum - node->data;
65
  return hasPathSum_revised(node->left, subSum) ||  hasPathSum_revised(node->right, subSum);
66
}
67
68
/*
69
Find the minimum in the binary tree - without making any assumptions.
70
Call this with an "impossible" minimum at top level.
71
*/
72
int findMin(struct node* node, int min) {
73
    if (!node) return min;
74
    if (node->data < min)
75
       min = node->data;
76
77
    int leftMin = findMin(node->left, min);
78
    if(leftMin < min)
79
       min = leftMin;
80
81
    int rightMin = findMin(node->right, min);
82
    if(rightMin < min)
83
       min = rightMin;
84
85
    return min;
86
}
87
88
/* UTILITY FUNCTIONS */
89
/* Helper function that allocates a new node with the
90
   given data and NULL left and right pointers. */
91
struct node* newnode(int data)
92
{
93
  struct node* node = (struct node*)
94
                       malloc(sizeof(struct node));
95
  node->data = data;
96
  node->left = NULL;
97
  node->right = NULL;
98
99
  return(node);
100
}
101
102
void freetree(struct node* node)
103
{
104
  if(!node)
105
    return;
106
  freetree(node->left);
107
  freetree(node->right);
108
  free(node);
109
}
110
111
/* Generate a random full binary tree where every path to a leaf has the
112
   totalsum given */
113
struct node* generatetree(struct node* node, unsigned depth, int totalsum) {
114
  if(depth == 0) {
115
    node->data = totalsum;
116
    return node;
117
  }
118
  node->data = (rand() % 100) - 50;
119
  node->left = newnode(0);
120
  node->right = newnode(0);
121
  generatetree(node->left, depth-1, totalsum - node->data);
122
  generatetree(node->right, depth-1, totalsum - node->data);
123
  return node;
124
}
125
126
void inspecttree(struct node* root, int expected_sum) {
127
  printf("Original:\n");
128
  if(hasPathSum_original(root, expected_sum))
129
    printf("There is a root-to-leaf path with sum %d\n", expected_sum);
130
  else
131
    printf("There is no root-to-leaf path with sum %d\n", expected_sum);
132
133
  printf("Revised:\n");
134
  if(hasPathSum_revised(root, expected_sum))
135
    printf("There is a root-to-leaf path with sum %d\n", expected_sum);
136
  else
137
    printf("There is no root-to-leaf path with sum %d\n", expected_sum);
138
  /* where was INT_MAX defined again :( */
139
  printf("Minimum: %d\n", findMin(root, 60000));
140
}
141
142
/* Driver program to test above functions*/
143
int main()
144
{
145
  srand(time(NULL));
146
  int sum = 21;
147
148
  /* Hand constructed binary tree is
149
            10
150
          /   \
151
        8      2
152
      /  \    /
153
    3     5  2
154
  */
155
  struct node *root = newnode(10);
156
  root->left        = newnode(8);
157
  root->right       = newnode(2);
158
  root->left->left  = newnode(3);
159
  root->left->right = newnode(5);
160
  root->right->left = newnode(2);
161
  inspecttree(root, sum);
162
  freetree(root);
163
164
  root = generatetree(newnode(0), 8, 1000);
165
  inspecttree(root, 1000);
166
  freetree(root);
167
168
  getchar();
169
  return 0;
170
}