簡體   English   中英

如何編寫遞歸函數來使用 C 中的有序遍歷在二叉樹中搜索鍵?

[英]How to write a recursive function to search for a key in a binary tree using in-order traversal in C?

我正在嘗試編寫一個遞歸函數,在給定二叉樹的根和一個鍵的情況下,使用中序遍歷搜索鍵。 如果未找到具有鍵的節點,則該函數返回 NULL; 否則它返回包含密鑰的節點。

我遇到的問題是返回包含密鑰的節點。 每次我調用函數並且鍵在二叉樹中時,函數返回NULL。 感覺結果一直被函數第一行的初始化覆蓋。

這是按順序搜索功能:

typedef struct treeNode
{
    int data;
    struct treeNode *left, *right;
} TreeNode, *TreeNodePtr;

typedef struct
{
    TreeNodePtr root;
} BinaryTree;

TreeNodePtr inOrderKey(TreeNodePtr root, int key)
{
    TreeNodePtr node = NULL;

    if (root != NULL)
    {
        node = inOrderKey(root->left, key);
        if(key == root->data)
        {
           node = root;
           return node;
        }
        node = inOrderKey(root->right, key);
    }

    return node;
}

這是主要功能:

int main()
{
    FILE * in = fopen("numbst.txt", "r");

    BinaryTree bst;
    bst.root = NULL;

    int num;

    fscanf(in, "%d", &num);
    while (num != 0)
    {
        if (bst.root == NULL)
            bst.root = newTreeNode(num);
        else
        {
            TreeNodePtr node = findOrInsert(bst, num);
        }
        fscanf(in, "%d", &num);
    }

    printf("\nThe in-order traversal is: ");
    inOrder(bst.root);
    printf("\nThe pre-order traversal is: ");
    preOrder(bst.root);

    TreeNodePtr keyNode;
    int count = 0;
    keyNode = inOrderKey(bst.root, 9);
    if (keyNode != NULL)
        count = 1;
    else
        count = 0;

    if (count == 1)
        printf("\n\n%d exists in the binary tree. In order traversal was used.\n", 9);
    else
        printf("\n\n%d doesn't exist in the binary tree. In order traversal was used.\n", 9);
        return 0;
}

我正在使用的二叉樹的有序遍歷是:1 2 3 4 5 7 9 21

二叉樹的前序遍歷為:4 1 2 3 7 5 21 9

我正在使用 9 和 31 測試該功能。

這段代碼:

    node = inOrderKey(root->left, key);
    if(key == root->data)
    {
       node = root;
       return node;
    }
    node = inOrderKey(root->right, key);

首先使用inOrderKey搜索左子樹。 然后它忽略結果。

然后它測試當前節點是否包含密鑰。 如果是,它返回給它的調用者。 如果調用者是自己(這是在遞歸調用中,而不是原始調用),則調用者可能會忽略結果。

然后它使用inOrderKey搜索正確的樹。 然后它返回結果。]

最終,包含密鑰的節點只有在最右邊的路徑中才會被返回。 如果它在任何節點的左子樹中,它將被忽略。

為了解決這個問題,在每次調用inOrderKey ,測試返回的值是否為空指針。 如果不是,請立即返回而不是繼續。

您遇到的問題是您堅持在不檢查是否已經找到密鑰的情況下導航整個樹

TreeNodePtr inOrderKey(TreeNodePtr root, int key)
{
    /* don't declare a local you don't know 
     * yet if you are going to use */

    /* better to check the opposite */
    if (root == NULL) 
        return NULL;  /* no tree, nothing can be found */

    TreeNodePtr node = inOrderKey(root->left, key);

    if (node) return node; /* we found it in the left child */
    if(key == root->data) { /* check here */
        /* you found it in this node */
        return root;
    }

    /* last chance, right child :) */
    return inOrderKey(root->right, key);
}

進行了驗證,所以這應該可以工作(我沒有測試過,因為你沒有發布一個完整且可驗證的例子,我對此表示歉意)

[已編輯 - 更新以用於順序遍歷]

左轉。 如果未找到密鑰,則檢查根目錄,如果密鑰不匹配,則正確遞歸。

TreeNodePtr inOrderKey(TreeNodePtr root, int key)
{
    TreeNodePtr node = NULL;
    if (root)
    {
        node = inOrderKey(root->left, key);
        if (node) {
            return node;
        }
        if (key == root->data)
        {
           return root;
        }
        node = inOrderKey(root->right, key);
    }
    return node;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM