为什么条件以奇怪的方式运作

时间:2017-12-05 04:41:54

标签: c if-statement search linked-list

我只是想在二叉搜索树中搜索密钥。 这就是我所做的。

int searchBST(int key,node *root){

    if(root->data == key){
        printf("The key %d is in the tree.\n",key);
        return 1;
    }
    if(root->left != NULL){
        searchBST(key,root->left);
        return 0;
    }
    if(root->right != NULL){
        searchBST(key,root->right);
        return 0;
    }
}

在main函数中,检查函数是否返回1,如果是,则键在树中。

printf("Please enter the key value you wish to search for: ");
scanf("%d",&key);
if((searchBST(key,root)) != 1)
    printf("The key %d is not in the tree.\n",key);

如果密钥不在树中,则会打印:

The key %d is not in the tree. 

这是正确的。所以这里有一个奇怪的部分,如果密钥在树中,有时系统会打印出来:

The key %d is in the tree. 

和其他时间系统将同时打印:

The key %d is in the tree.
The key %d is not in the tree.

那么我该怎么做才能解决它?

这是我的整个代码

#include<stdio.h>
#include<malloc.h>
// This program will create a binary search tree or a max-heap, as chosen from a menu.
typedef struct BSTNode{
int data;
struct Node *left;
struct Node *right;
}node;
node* getNewNode(int data){
    node *new = (node*)malloc(sizeof(node));
    new->data = data;
    new->left = new->right = NULL;
    return new;
}
void heapPreOrder(int heapRootIndex,int array[],int numOfNodes){
int i = heapRootIndex;
printf("%d\t",array[i]);
if( 2*i+1<numOfNodes)
    heapPreOrder(2*i+1,array,numOfNodes);
if(2*i+2<numOfNodes)
    heapPreOrder(2*i+2,array,numOfNodes);
}
void disLevelOrder(int array[],int numOfNodes){
int i;
for(i = 0;i < numOfNodes;i++){
    printf("%d\t",array[i]);
}
printf("\n");
}
node* insertBST(int data,node *root){
if(root == NULL){
    root = getNewNode(data);
}
else{
    if(data <= root->data){
        root->left = insertBST(data,root->left);
    }
        else if(data >= root->data)
        root->right= insertBST(data,root->right);
    }
    return root;

}

int searchBST(int key,node *root){

 if (!root) return 0;
if (root->data == key) return 1;
if (root->data > key) return searchBST(root->left, key);
return searchBST(root->right, key);
}
void levelOrder(node* root, int level){
if (root == NULL)
    return;
if (level == 1)
    printf("%d\t", root->data);
else if (level > 1)
{
    levelOrder(root->left, level-1);
    levelOrder(root->right, level-1);
}
}
int findHeight(node* root)
{
if (root==NULL)
    return 0;
else
{
    int leftHeight = findHeight(root->left);
    int rightHeight = findHeight(root->right);

    if(leftHeight >= rightHeight)
        return leftHeight+1;
    else
        return rightHeight+1;
}

}
void insertHeap(int key,int numOfNodes,int array[]){
int i,j;
i = numOfNodes-1;
if(i%2 == 1 && array[i] > array[(i-1)/2]){  //if left child is greater than parent
            swap(&array[i],&array[(i-1)/2]);
            for(j = (i-1)/2;j > 0,array[j]>array[(j- 1)/2]; j = (j- 1)/2){
                swap(&array[j],&array[(j-1)/2]);
            }
        }
        if(i%2 == 0 && array[i] > array[(i-2)/2]){//if right child is greater than parent
            swap(&array[i],&array[(i-2)/2]);
            for(j = (i-1)/2;j > 0,array[j]>array[(j- 1)/2]; j = (j- 1)/2){
                swap(&array[j],&array[(j-1)/2]);
            }
        }
}
void searchHeap(int key,int array[],int numOfNodes){
int i;
for(i = 0;i < numOfNodes;i++){
    if(key == array[i]){
        printf("The key %d is in the heap.\n",key);
        return;
    }
}
printf("The key %d is not in the heap.\n",key); 
}
void preorder(node *root){
if(root!=NULL){
    printf("%d\t",root->data);
    preorder(root->left);
    preorder(root->right);
}
}
void swap(int *a,int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;

}
int main(){
int i,j,numOfNodes,key,height;
char choice,option;
node *root = (node*)malloc(sizeof(node));       //initialize root;
root = NULL;
printf("Enter the number of nodes in the linked list to be initially created: ");
scanf("%d",&numOfNodes);
int array[numOfNodes];           //store all the data in the array first
printf("Enter the data value to be placed in the node: ");
scanf("%d",&array[0]);
root = insertBST(array[0],root);           //create the root
//root->left = getNewNode(array[0]);
for(i = 1;i < numOfNodes;i++){
    printf("Enter the data value to be placed in the node: ");                 //put each data into array, leave the index 0 empty
    scanf("%d",&array[i]);
}
printf("What do you wish to create a Binary search Tree (B) or a Max-Heap (H)?: ");
scanf(" %c",&choice);
if(choice == 'B' || choice == 'b'){         //if user wants to build a Binary search Tree
    for(i = 1;i<numOfNodes;i++){
        insertBST(array[i],root);
    }
        printf("Binary search tree build successfully.\n");
}


if(choice == 'H'|| choice == 'h'){         //if user wants to build a Max-Heap
        for(i = 1;i<numOfNodes;i++){          //build the max heap
        if(i%2 == 1 && array[i] > array[(i-1)/2]){  //if left child is greater than parent
            swap(&array[i],&array[(i-1)/2]);
            for(j = (i-1)/2;j > 0,array[j]>array[(j- 1)/2]; j = (j- 1)/2){
                swap(&array[j],&array[(j-1)/2]);
            }
        }
        if(i%2 == 0 && array[i] > array[(i-2)/2]){  //if right child is greater than parent
            swap(&array[i],&array[(i-2)/2]);
            for(j = (i-1)/2;j > 0,array[j]>array[(j- 1)/2]; j = (j- 1)/2){
                swap(&array[j],&array[(j-1)/2]);
            }
        }
    }
        printf("Heap successfully created.\n");
    }
while(choice == 'B'||choice == 'b'){
    printf("What do you wish to do?\n");
    printf("Show Preorder Traversal(P)\tShow Level order Traversal(L)\tSearch(S)\tInsert(I)\tQuit(Q)\n");
    printf("Please enter a choice: ");
    scanf(" %c",&option);
        if(option == 'p'||option == 'P'){
        preorder(root);
        printf("\n");
    }
    if(option == 'L'||option == 'l'){
        height = findHeight(root);
        for(i = 1;i <= height;i++){
            levelOrder(root,i);
        }
        printf("\n");
    }
    if(option == 'S'||option == 's'){     //This is the part I have trouble with
        printf("Please enter the key value you wish to search for: ");
        scanf("%d",&key);
        if((searchBST(key,root)) != 1)
        printf("The key %d is not in the tree.\n",key);
    }
    if(option == 'I'||option == 'i'){       //if user wants to insert a number
        printf("please enter the key value you wish to insert: ");
        scanf("%d",&key);
        insertBST(key,root);
        printf("The key value %d was successfully inserted.\n",key);
    }
    if(option == 'q'||option == 'Q'){
        printf("Thanks for using my program, please rate 100 as feedback! Have a wonderful day :)");
        return 0;
    }
    printf("\n");
}
while(choice == 'H'|| choice == 'h'){
    printf("What do you wish to do?\n");
    printf("Show Preorder Traversal(P)\tShow Level order Traversal(L)\tSearch(S)\tInsert(I)\tQuit(Q)\n");
    printf("Please enter a choice: ");
    scanf(" %c",&option);
    if(option == 'p'||option == 'P'){
        heapPreOrder(0,array,numOfNodes);
        printf("\n");
    }
    if(option == 'L'||option == 'l'){
        disLevelOrder(array,numOfNodes);
        printf("\n");
    }
    if(option == 'S'||option == 's'){
        printf("Please enter the key value you wish to search for: ");
        scanf("%d",&key);
        searchHeap(key,array,numOfNodes);
    }
    if(option == 'I'||option == 'i'){       //if user wants to insert a number
        printf("please enter the key value you wish to insert: ");
        scanf("%d",&key);
        numOfNodes++;
        array[numOfNodes-1] = key;
        insertHeap(key,numOfNodes,array);
        printf("The key value %d was successfully inserted.\n",key);
    }
    if(option == 'q'||option == 'Q'){
        printf("Thanks for using my program, please rate 100 as feedback! Have a wonderful day :)");
        return 0;
    }
    printf("\n");
}

}

3 个答案:

答案 0 :(得分:0)

您不应在整个二叉搜索树中搜索密钥。您应该遵循正确的路径。这就是为什么你应该将你的密钥与当前的根值进行比较。如果该值与key相同,则这是输出。如果密钥小于根值,则应该转到左子树,否则右转。

int searchBST(int key, node* root) {
    if (!root) return 0;
    if(root->data == key) {
        printf("The key %d is in the tree.\n",key);
        return 1;
    }
    if (root->data > key) return searchBST(key, root->left);
    return searchBST(key, root->right);
}

在您的情况下,即使您找到了密钥,也会遍历整棵树。这就是为什么有时你得到两个输出。

答案 1 :(得分:0)

试试这个:

int searchBST(int key,node *root){
    if (!root){
        return 0;
    }
    if(root->data == key){
        printf("The key %d is in the tree.\n",key);
        return 1;
    }
    if(root->left != NULL){
        return searchBST(key,root->left);
        //return 0;
    }
    if(root->right != NULL){
        return searchBST(key,root->right);
        //return 0;
    }
}

答案 2 :(得分:0)

编辑答案 - :

  1. 问题在于返回值。即使您找到了密钥,在下一个迭代循环中,您将返回值0.这将在您的main函数中检查,并将报告为未找到密钥。
  2. 其次,搜索未在节点的右侧链接中完成。
  3. 添加条目(尤其是第一个条目)时,根链表中的条目重复。
  4. 只需像这样更改您的代码,

       int searchBST(int key,node *root){
    
           int bRet = 1;  /// 1 means error
           if(root->data == key){
               printf("The key %d is in the tree.\n",key);
               bRet = 0;  /// 0 means success
               return bRet;
           }
           if(root->left != NULL){
               bRet = searchBST(key,root->left);
               if(!bRet)
               {
                   return bRet;
               }
           }
           if(root->right != NULL){
               bRet = searchBST(key,root->right);
               if(!bRet)
               {
                   return bRet;
               }
           }
    
           return bRet;
      }
    

    主要功能,

      printf("Please enter the key value you wish to search for: ");
      scanf("%d",&key);
      if(0 != searchBST(key,root))
         printf("The key %d is not in the tree.\n",key);
    

    返回值0表示成功,任何其他值(包括1表示未找到错误/密钥。

    我发现了一些小问题,但我认为这些问题应该在编译时发现,比如,

    1. int array [numOfNodes];数组声明需要一个const数而不是一个变量。
    2. 使用Node代替节点。
    3. 使用&#34; new&#34;关键字作为变量。
    4. 将交换功能定义为高于其用途。