|  | /* | 
|  | Redistribution and use in source and binary forms, with or without | 
|  | modification, are permitted provided that the following conditions are met: | 
|  |  | 
|  | * Redistributions of source code must retain the above copyright | 
|  | notice, this list of conditions and the following disclaimer. | 
|  |  | 
|  | * Redistributions in binary form must reproduce the above copyright | 
|  | notice, this list of conditions and the following disclaimer in the | 
|  | documentation and/or other materials provided with the distribution. | 
|  |  | 
|  | * Neither the name of "The Computer Language Benchmarks Game" nor the | 
|  | name of "The Computer Language Shootout Benchmarks" nor the names of | 
|  | its contributors may be used to endorse or promote products derived | 
|  | from this software without specific prior written permission. | 
|  |  | 
|  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
|  | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|  | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
|  | ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | 
|  | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
|  | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
|  | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 
|  | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 
|  | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
|  | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
|  | POSSIBILITY OF SUCH DAMAGE. | 
|  | */ | 
|  |  | 
|  | /* The Computer Language Shootout Benchmarks | 
|  | http://shootout.alioth.debian.org/ | 
|  |  | 
|  | contributed by Kevin Carson | 
|  | compilation: | 
|  | gcc -O3 -fomit-frame-pointer -funroll-loops -static binary-trees.c -lm | 
|  | icc -O3 -ip -unroll -static binary-trees.c -lm | 
|  | */ | 
|  |  | 
|  | #include <malloc.h> | 
|  | #include <math.h> | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  |  | 
|  |  | 
|  | typedef struct tn { | 
|  | struct tn*    left; | 
|  | struct tn*    right; | 
|  | long          item; | 
|  | } treeNode; | 
|  |  | 
|  |  | 
|  | treeNode* NewTreeNode(treeNode* left, treeNode* right, long item) | 
|  | { | 
|  | treeNode*    new; | 
|  |  | 
|  | new = (treeNode*)malloc(sizeof(treeNode)); | 
|  |  | 
|  | new->left = left; | 
|  | new->right = right; | 
|  | new->item = item; | 
|  |  | 
|  | return new; | 
|  | } /* NewTreeNode() */ | 
|  |  | 
|  |  | 
|  | long ItemCheck(treeNode* tree) | 
|  | { | 
|  | if (tree->left == NULL) | 
|  | return tree->item; | 
|  | else | 
|  | return tree->item + ItemCheck(tree->left) - ItemCheck(tree->right); | 
|  | } /* ItemCheck() */ | 
|  |  | 
|  |  | 
|  | treeNode* BottomUpTree(long item, unsigned depth) | 
|  | { | 
|  | if (depth > 0) | 
|  | return NewTreeNode | 
|  | ( | 
|  | BottomUpTree(2 * item - 1, depth - 1), | 
|  | BottomUpTree(2 * item, depth - 1), | 
|  | item | 
|  | ); | 
|  | else | 
|  | return NewTreeNode(NULL, NULL, item); | 
|  | } /* BottomUpTree() */ | 
|  |  | 
|  |  | 
|  | void DeleteTree(treeNode* tree) | 
|  | { | 
|  | if (tree->left != NULL) | 
|  | { | 
|  | DeleteTree(tree->left); | 
|  | DeleteTree(tree->right); | 
|  | } | 
|  |  | 
|  | free(tree); | 
|  | } /* DeleteTree() */ | 
|  |  | 
|  |  | 
|  | int main(int argc, char* argv[]) | 
|  | { | 
|  | unsigned   N, depth, minDepth, maxDepth, stretchDepth; | 
|  | treeNode   *stretchTree, *longLivedTree, *tempTree; | 
|  |  | 
|  | N = atol(argv[1]); | 
|  |  | 
|  | minDepth = 4; | 
|  |  | 
|  | if ((minDepth + 2) > N) | 
|  | maxDepth = minDepth + 2; | 
|  | else | 
|  | maxDepth = N; | 
|  |  | 
|  | stretchDepth = maxDepth + 1; | 
|  |  | 
|  | stretchTree = BottomUpTree(0, stretchDepth); | 
|  | printf | 
|  | ( | 
|  | "stretch tree of depth %u\t check: %li\n", | 
|  | stretchDepth, | 
|  | ItemCheck(stretchTree) | 
|  | ); | 
|  |  | 
|  | DeleteTree(stretchTree); | 
|  |  | 
|  | longLivedTree = BottomUpTree(0, maxDepth); | 
|  |  | 
|  | for (depth = minDepth; depth <= maxDepth; depth += 2) | 
|  | { | 
|  | long    i, iterations, check; | 
|  |  | 
|  | iterations = pow(2, maxDepth - depth + minDepth); | 
|  |  | 
|  | check = 0; | 
|  |  | 
|  | for (i = 1; i <= iterations; i++) | 
|  | { | 
|  | tempTree = BottomUpTree(i, depth); | 
|  | check += ItemCheck(tempTree); | 
|  | DeleteTree(tempTree); | 
|  |  | 
|  | tempTree = BottomUpTree(-i, depth); | 
|  | check += ItemCheck(tempTree); | 
|  | DeleteTree(tempTree); | 
|  | } /* for(i = 1...) */ | 
|  |  | 
|  | printf | 
|  | ( | 
|  | "%li\t trees of depth %u\t check: %li\n", | 
|  | iterations * 2, | 
|  | depth, | 
|  | check | 
|  | ); | 
|  | } /* for(depth = minDepth...) */ | 
|  |  | 
|  | printf | 
|  | ( | 
|  | "long lived tree of depth %u\t check: %li\n", | 
|  | maxDepth, | 
|  | ItemCheck(longLivedTree) | 
|  | ); | 
|  |  | 
|  | return 0; | 
|  | } /* main() */ |