//find closest value
void
closestValue(TreeNode* node, unsigned val)
{
	//traverse the tree
	//if val is found, return it
	//record the min difference
	if (!node)
	{
		return;
	}
	
	++counter;
	if (node->val == val)
	{
		found = val;
		return;
	}

	unsigned cdiff = abs(node->val - val);
	if (cdiff < diff)
	{
		found = node->val;
		diff = cdiff;
	}

	if (node->val > val)
	{
		closestValue(node->left, val);

	}
	else
	{
		closestValue(node->right, val);
	}
}
 int closestValue(TreeNode* root, double target) {
     if (!root) return INT_MAX;
     if (!(root -> left) && !(root -> right)) return root -> val;
     int left = closestValue(root -> left, target);
     int right = closestValue(root -> right, target);
     double td = abs(root -> val - target), ld = abs(left - target), rd = abs(right - target);
     if (td < ld) return td < rd ? root -> val : right;
     else return ld < rd ? left : right;
 }
 int closestValue(TreeNode* root, double target) {
     int closest = root->val;
     if(root->val > target and root->left) {
         int leftClosest = closestValue(root->left, target);
         if(abs(target - leftClosest) < abs(target - closest)) {
             closest = leftClosest;
         }
     } else if(root->val < target and root->right) {
         int rightClosest = closestValue(root->right, target);
         if(abs(target - rightClosest) < abs(target - closest)) {
             closest = rightClosest;
         }   
     }
     return closest;
 }
 int closestValue(TreeNode* root, double target) {
     int a = root->val;
     TreeNode* kid = target < a ? root->left : root->right;
     if(!kid) return a;
     int b = closestValue(kid, target);
     return abs(a-target) < abs(b-target) ? a : b;
 }
 int closestValue(TreeNode* root, double target) {
     int now = root->val;
     TreeNode* next = target < now ? root->left : root->right;
     if (!next) return now;
     int nextVal = closestValue(next, target);
     return abs(now - target) < abs(nextVal - target) ? now : nextVal;
 }
 int closestValue(TreeNode* root, double target) {
     auto kid = root->val >= target ? root->left : root->right;
     if (kid == nullptr) {
         return root->val;
     } else {
         int kidClosestValue = closestValue(kid, target);
         return abs(kidClosestValue - target) < abs(root->val - target) ? kidClosestValue : root->val;
     }
 }
    int closestValue(TreeNode* root, double target) {
        int cur = root->val;
        TreeNode* child = target < cur ? root->left : root->right;

        if (child == NULL) {
            return cur;
        }
        int child_val = closestValue(child, target);

        return abs(cur - target) < abs(child_val - target) ? cur : child_val;
    }
 int closestValue(TreeNode* root, double target) 
 {
     int a = root->val;
     TreeNode* nxt = target<a ? root->left : root->right;
     
     if(!nxt)
         return a;
     
     int b = closestValue(nxt, target);
     return fabs(a-target)<fabs(b-target) ? a : b;
 }
//recursive
int closestValue(TreeNode *root,double target) {
    if(!root) {
      return 0;
    }
    int a = root->val;
    if(target < a) {
      root = root->left;  
    } else {
      root = root->right;  
    }
    if (!root) return a;
    int b = closestValue(root, target);
    if (abs(a - target) < abs(b - target) ) {
      return a;
    } 
    return b;
}
		void Main()
		{
			print(closestValue(new TreeNode(1), 4.428571));
		}
int main()
{
	//create tree node
	TreeNode* root = 0;
	insert(root, 1);
	insert(root, 8);
	insert(root, 3);
	insert(root, 4);
	insert(root, 6);
	insert(root, 7);
	insert(root, 10);
	insert(root, 13);
	insert(root, 14);
	insert(root, 14);
	insert(root, 15);
	
	std::cout<<"preOrder:";
	preOrder(root);
	std::cout<<"\n";

	std::cout<<"postOrder:";
	postOrder(root);
	std::cout<<"\n";

	std::cout<<"inOrder:";
	inOrder(root);
	std::cout<<"\n";

	std::cout<<"bfs:\n";
	bfs(root);
	std::cout<<"\n";

	{
		unsigned celem = 10;
		bool found = nonRecursiveSearch(root, celem);
		std::cout<<"found "<< celem << " : "<< (found? std::string("yes") : std::string("no"))<<std::endl;
	}

	{
		unsigned celem = 15;
		bool found = nonRecursiveSearch(root, celem);
		std::cout<<"found "<< celem << " : "<< (found? std::string("yes") : std::string("no"))<<std::endl;
	}
	{
		unsigned celem = 7;
		bool found = nonRecursiveSearch(root, celem);
		std::cout<<"found "<< celem << " : "<< (found? std::string("yes") : std::string("no"))<<std::endl;
	}

	unsigned closest = findClosestElem(root);
	std::cout<<"closest to root: "<<closest<<"\n";
	
	closestValue(root, 20);
	std::cout<<"closest to 20: "<<found<<" diff:" <<diff<<" in "<<counter<<" traversals\n";

	
	found = 0;
	diff = -1;
	counter = 0;
	closestValue(root, 12);
	std::cout<<"closest to 12: "<<found<<" diff:" <<diff<<" in "<<counter<<" traversals\n";

	std::cout<<"max level: "<<maxDepth(root)<<"\n";
	std::cout<<"min level: "<<minDepth(root)<<"\n";
	
	std::cout<<"all possible paths:\n";
	IntVector tmp;
	allPossiblePaths(root, tmp);
	
	{
		std::cout<<"-----------------------------------\n";
		bfs(root);
		std::cout<<"Nodes in range [10..15]: "<<nodesInRange(root, 10, 15)<<"\n";
	}
	
	deleteTree(root);
	
	return 0;
}