C 计算二进制搜索树中的比较数

C 计算二进制搜索树中的比较数,c,recursion,comparison,binary-tree,binary-search-tree,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

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

#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;
}
#杂注警告(禁用:4996)
#包括
#包括
typedef-int-Titem;
typedef结构节点*Tpointer;
类型定义结构节点{
滴度项目;
t点左;
t指向权;
}Tnode;
类型定义t指针t指示树;
void初始化(TBinSTree*bintree);
无效插入目录树(TBinSTree*bintree,Titem项);
int isInTree(TBinSTree*bintree,滴度项目,int*计数器);
无效打印树(TBinSTree bintree);
#包括“bintree.h”
void初始化(TBinSTree*bintree){
*bintree=NULL;
}
无效插入到树(TBinSTree*bintree,Titem newitem){
Tpointer newnode=*bintree;
if(*bintree==NULL){//如果树为空
newnode=(Tpointer)malloc(sizeof(Tnode));
newnode->left=NULL;
newnode->right=NULL;
newnode->item=newitem;
*bintree=newnode;
}
否则{
如果(新建节点->项目>新建项目)
将\插入\树(&newnode->left,newitem);
if(newnode->itemright,newitem);
}
}
int isInTree(TBinSTree*bintree、Titem项目、int*计数器){
t指针电流=*bintree;
(*计数器)+;
if(current==NULL){//Base case==空树
printf(“项目%d不在目录树中,\n”,项目);
printf(“比较次数(大小写为NULL)为:%d\n”,*计数器);
返回1;
}
否则{
如果(当前->项目==项目){//请查看是否在此处找到
printf(“项目%d在树\n中”,项目);
printf(“比较次数(case node.item==item)为:%d\n”,*计数器);
返回0;
}
else{//否则将沿着正确的子树重复出现
如果(项目<当前->项目)
返回isInTree(&当前->左侧,项目,计数器);
其他的
返回isInTree(&当前->右侧,项目,计数器);
}
}
}
void print_树(TBinSTree bintree){//按顺序遍历
if(bintree!=NULL){
打印树(bintree->左侧);
printf(“%d\n”,bintree->item);
打印树(bintree->右侧);
}
}
#包括“bintree.h”
#包括
#定义数字10000
内部主(空){
srand(时间(空));
t梧桐树;
int item_to_search;
整数计数=0;
初始化(&树);
对于(int i=0;i
UPD1 我已经更新了代码,但是现在NULL case print语句被调用了两次。 UPD2
这是适用于我的应用程序的代码的最终版本。

您也可以在调用计数器时传递对它的引用,例如

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);
        }
    }
}
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);

将其传递到下一个递归中:这样,您可以对函数的不同调用使用不同的计数器变量。

如果他使用多个线程,这将给出有偏差的结果。这是一个很好的观点,谢谢!但是,如果我想在函数内部而不是在main中打印计数器,该怎么办?您需要使用
*counter
再次取消对该数字的引用-是。我已经将其添加到我的代码中。顺便说一下,我怀疑你每次迭代只关心一个比较:我不认为空校验计数,你也可以考虑将项目和当前节点的项目作为一个单一的比较。在这种情况下,您实际上只是在计算递归到的树的深度。
counter = 0;
isInTree(...); //call to search
//print counter variable.


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