2010-03-24 88 views
5

我是一個Python傢伙。學習C語言,我一直試圖在C中實現二叉搜索樹。我寫下了代碼,並且我一直試着從幾個小時,但不能按預期得到輸出。請幫忙!C中的二叉搜索樹

請糾正我。

#include<stdlib.h> 
#include<stdio.h> 

typedef int ElementType; 

typedef struct TreeNode { 
    ElementType element; 
    struct TreeNode *left, *right; 
} TreeNode; 

TreeNode *createTree(){ 
    //Create the root of tree 
    TreeNode *tempNode; 
    tempNode = malloc(sizeof(TreeNode)); 
    tempNode->element = 0; 
    tempNode->left = NULL; 
    tempNode->right = NULL; 
    return tempNode; 
} 

TreeNode *createNode(ElementType X){ 
    //Create a new leaf node and return the pointer 
    TreeNode *tempNode; 
    tempNode = malloc(sizeof(TreeNode)); 
    tempNode->element = X; 
    tempNode->left = NULL; 
    tempNode->right = NULL; 
    return tempNode; 
} 

TreeNode *insertElement(TreeNode *node, ElementType X){ 
    //insert element to Tree 
    if(node==NULL){ 
     return createNode(X); 
    } 
    else{ 
     if(X < node->element){ 
      node->left = insertElement(node->left, X); 
     } 
     else if(X > node->element){ 
      node->right = insertElement(node->right, X); 
     } 
     else if(X == node->element){ 
      printf("Oops! the element is already present in the tree."); 
     } 
    } 
} 

TreeNode *displayTree(TreeNode *node){ 
    //display the full tree 
    if(node==NULL){ 
     return; 
    } 
    displayTree(node->left); 
    printf("| %d ", node->element); 
    displayTree(node->right); 
} 

main(){ 
    //pointer to root of tree #2 
    TreeNode *TreePtr; 
    TreeNode *TreeRoot; 
    TreeNode *TreeChild; 

    //Create the root of tree 
    TreePtr = createTree(); 

    TreeRoot = TreePtr; 

    TreeRoot->element = 32; 
    printf("%d\n",TreeRoot->element); 

    insertElement(TreeRoot, 8); 
    TreeChild = TreeRoot->left; 
    printf("%d\n",TreeChild->element); 

    insertElement(TreeRoot, 2); 
    insertElement(TreeRoot, 7); 
    insertElement(TreeRoot, 42); 
    insertElement(TreeRoot, 28); 
    insertElement(TreeRoot, 1); 
    insertElement(TreeRoot, 4); 
    insertElement(TreeRoot, 5); 

// the output is not as expected :(
    displayTree(TreeRoot); 
} 
+0

究竟是 「無法得到的輸出如預期」 是什麼意思? – Naveen 2010-03-24 10:44:37

+0

調試您的代碼並找到確切的問題。 – medopal 2010-03-24 10:46:50

+0

@Naveen我得到| 5 | 32 | 42調用displayTree()函數時。我希望它能打印剩餘的元素。 – heapzero 2010-03-24 10:47:03

回答

5

問題在於插入。如果nodeNULL,則創建一個新節點並將其返回。但是如果節點不是NULL。您正在對右/左子樹進行正確更改,但是您沒有返回任何內容。

變化

if(X < node->element){ 
    node->left = insertElement(node->left, X); 
} 
else if(X > node->element){ 
    node->right = insertElement(node->right, X); 
} 

到:

if(X < node->element){ 
    node->left = insertElement(node->left, X); 
    return node; // add this. 
} 
else if(X > node->element){ 
    node->right = insertElement(node->right, X); 
    return node; // add this. 
} 
+0

哇!有用..!非常感謝codaddict! 但是,無法弄清楚它的工作原理。 這個返回值'node'去哪了? 對不起,關於這個愚蠢的問題:) – heapzero 2010-03-24 10:58:59

+0

@heapzero:將返回值設置爲父節點的子節點。如果你沒有返回任何東西,那麼它可能拾取最後創建的節點並將其附加爲父節點的子節點。因此,您新創建的節點已被添加爲僅作爲根節點的子節點。 – Naveen 2010-03-24 11:06:08

+0

謝謝@Naveen!現在有道理! – heapzero 2010-03-24 11:13:40

2

您的insertElement並不總是返回一個值。這就是爲什麼你的遞歸調用出錯。告訴你的編譯器警告你類似的錯誤(例如,在gcc上,使用-Wall)。

displayTree有一個類似的錯誤,當它被指定返回一個TreeNode*時什麼也不返回。

main也應該返回一個值(或者你應該聲明它的void)。

+1

Afaik自C99以來已棄用聲明'main'爲返回'void'。 – 2010-03-24 10:58:01

+0

@Thomas謝謝!根據codeaddict建議的代碼,現在'insertElement()'函數返回一個值。有用! – heapzero 2010-03-24 11:09:43

+0

@Felix:它並不真正被廢棄:C99允許實現定義的入口點,並且有關於main()的返回類型的說法如下:「如果返回類型與int不兼容,終止狀態返回到主機環境未指定「;出於可移植性的原因,你應該儘可能地避免實現定義和未指定的行爲,即堅持'int main(void)'和'int main(int argc,char * argv [])' – Christoph 2010-03-24 11:20:36