计算二叉搜索树中的比较次数

时间:2014-04-26 13:32:02

标签: c recursion comparison binary-tree binary-search-tree

我想计算在二叉搜索树中查找数据所需的比较次数。 到目前为止,我有一个功能,检查数据是否在树中。我对如何计算比较感到困惑,因为函数是递归的。我需要使用全局变量吗?但在这种情况下,它将一直保持不变,我不能第二次使用它。谢谢!

#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>

typedef int Titem;
typedef struct node* Tpointer;
typedef struct node{
    Titem item;
    Tpointer left;
    Tpointer right;
}Tnode;
typedef Tpointer TBinSTree;

void initialize(TBinSTree* bintree);
void insert_to_tree(TBinSTree* bintree, Titem item);
int isInTree(TBinSTree* bintree, Titem item, int* counter);
void print_tree(TBinSTree bintree);

#include "bintree.h"

void initialize(TBinSTree* bintree){
    *bintree = NULL;
}
void insert_to_tree(TBinSTree* bintree, Titem newitem){
    Tpointer newnode = *bintree;
    if (*bintree == NULL){// if tree is empty
        newnode = (Tpointer)malloc(sizeof(Tnode));
        newnode->left = NULL;
        newnode->right = NULL;
        newnode->item = newitem;
        *bintree = newnode;
    }
    else{
        if (newnode->item > newitem)
            insert_to_tree(&newnode->left, newitem);
        if (newnode->item < newitem)
            insert_to_tree(&newnode->right, newitem);
    }
}
int isInTree(TBinSTree* bintree, Titem item, int* counter){
    Tpointer current = *bintree;
    (*counter)++;
    if (current == NULL){// Base case == empty tree
        printf("Item %d is not in the tree\n", item);
        printf("Number of comparisons (case NULL) is: %d\n", *counter);
        return 1;
    }
    else {
        if (current->item == item){ //see if found here
            printf("Item %d is in the tree\n", item);
            printf("Number of comparisons (case node.item == item) is: %d\n", *counter);
            return 0;
        }
        else{ //otherwise recur down the correct subtree
            if (item < current->item)
                return isInTree(&current->left, item, counter);
            else
                return isInTree(&current->right, item, counter);
        }
    }
}
void print_tree(TBinSTree bintree){ // inorder traverse
    if (bintree != NULL) {
        print_tree(bintree->left);
        printf("%d\n", bintree->item);
        print_tree(bintree->right);
    }
}

#include "bintree.h"
#include <time.h>

#define NUMBERS 10000

int main(void){

    srand(time(NULL));
    TBinSTree tree;
    int item_to_search;
    int count = 0;

    initialize(&tree);
    for (int i = 0; i < NUMBERS; i++){
        insert_to_tree(&tree, rand() % 10000);
    }
    for (int i = 0; i < 3; i++){
        count = 0;
        printf("Input %d item to search: ", i+1);
        scanf("%d", &item_to_search);
        isInTree(&tree, item_to_search, &count);
    }
    return 0;
}

UPD1 我已更新代码,但现在NULL case print语句被调用两次。 的 UPD2 这是适用于我的应用程序的最终代码版本。

2 个答案:

答案 0 :(得分:2)

当你打电话时,你也可以传递对计数器的引用,例如

int isInTree(TBinSTree* bintree, Titem item, int* counter)
{
    ...
    if (counter != null)
    {
        (*counter)++;
        printf("Number of comparisons is %d\n", *counter);
    }
    ...
        return isInTree(&tmp->left, item, counter);
    ...
}

int counter = 0;
isInTree(foo, bar, &counter);

将它传递给下一个递归:这样你就可以使用不同的计数器变量来调用函数。

答案 1 :(得分:0)

int counter = 0;
int isInTree(TBinSTree* bintree, Titem item){

    Tpointer tmp = *bintree;
    counter++;
    if (tmp == NULL){// Base case == empty tree
        printf("Number of comparisons is: \n", counter);
        return 1;
    }
    else {
        counter++;
        if (tmp->item == item){ //see if found here
            printf("Number of comparisons is: \n", counter);
            return 0;
        }
        else{ //otherwise recur down the correct subtree
            counter++;
            if (item < tmp->item)
                return isInTree(&tmp->left, item);
            else
                return isInTree(&tmp->right, item);
        }
    }
}

使用全局变量并将其设置为0,同时再次调用搜索功能。

counter = 0;
isInTree(...); //call to search
//print counter variable.


counter = 0;
isInTree(...); //another call to search
//print counter variable.