C语言数据结构之二叉树(BINARY TREE)链式存贮的简单实现
C语言数据结构之二叉树(BINARY TREE)链式存贮的简单实现
- 树型数据结构在应用中非常多,效率也非常好,只是结构相对复杂,理解起来有点儿难度!!!
定义数据结构
typedef struct _BTreeNode BTreeNode;
struct _BTreeNode {int val;BTreeNode *lchild, *rchild;
};
- 自定义结构体数据类型BTreeNode,成员包括val保存数据,lchild左子结点,rchild右子结点
- 链式存贮,对编程来说更直观!!!
- 为了便于测试,节点只保存整数!!!
- 创建二叉树节点函数btree_node_new
- 释放二叉树函数btree_free
代码如下:
/* filename: btree.c */
#include <stdio.h>
#include <stdlib.h>/* compile : gcc btree.c -o btree */
/* run : ./btree *//* define function pointer BTFunc for output */
typedef void (*BTFunc) (int val);/* define the BTreeNode datatype */
typedef struct _BTreeNode BTreeNode;
struct _BTreeNode {int val;BTreeNode *lchild, *rchild;
};/* create new BTreeNode */
BTreeNode *
btree_node_new (int val)
{BTreeNode *node = (BTreeNode*) malloc (sizeof(BTreeNode));node->val = val;node->lchild = NULL;node->rchild = NULL;return node;
}/* free a btree, every nodes in BTreeNode *root, recursion */
void
btree_free (BTreeNode *root)
{if (root != NULL){btree_free (root->lchild);btree_free (root->rchild);free (root);}
}/********************************//**/
void
test_tree_append (void)
{BTreeNode *root = btree_node_new (100);btree_free (root);
}/**/
int
main (int argc, char *argv[])
{test_tree_append ();return 0;
}
/* --[.^.]-- */
编译运行,顺利通过,检测内存,达到预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree
songvm@ubuntu:~/works/xdn/too$ valgrind --leak-check=yes ./btree
==3507== Memcheck, a memory error detector
==3507== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3507== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3507== Command: ./btree
==3507==
==3507==
==3507== HEAP SUMMARY:
==3507== in use at exit: 0 bytes in 0 blocks
==3507== total heap usage: 1 allocs, 1 frees, 24 bytes allocated
==3507==
==3507== All heap blocks were freed -- no leaks are possible
==3507==
==3507== For counts of detected and suppressed errors, rerun with: -v
==3507== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/too$
为树节点追加子节点,左侧追加append_left,右侧追加append_right,中序遍历inorder_traversal
- 追加左子节点append_left,追加右子节点append_right
- 中序遍历inorder_traversal 顺序为:左->根->右,用递归来实现!!!
代码如下:
/* filename: btree.c */
#include <stdio.h>
#include <stdlib.h>/* compile : gcc btree.c -o btree */
/* run : ./btree *//* define function pointer BTFunc for output */
typedef void (*BTFunc) (int val);/* define the BTreeNode datatype */
typedef struct _BTreeNode BTreeNode;
struct _BTreeNode {int val;BTreeNode *lchild, *rchild;
};/* create new BTreeNode */
BTreeNode *
btree_node_new (int val)
{BTreeNode *node = (BTreeNode*) malloc (sizeof(BTreeNode));node->val = val;node->lchild = NULL;node->rchild = NULL;return node;
}/* free a btree, every nodes in BTreeNode *root, recursion */
void
btree_free (BTreeNode *root)
{if (root != NULL){btree_free (root->lchild);btree_free (root->rchild);free (root);}
}/* append left child node to root with val */
void
btree_append_left (BTreeNode *root, int val)
{BTreeNode *node = btree_node_new (val);root->lchild = node;
}/* append right child node to root with val*/
void
btree_append_right (BTreeNode *root, int val)
{BTreeNode *node = btree_node_new (val);root->rchild = node;
}/* inorder traversal, left->root->right */
void
btree_inorder_traversal (BTreeNode *root)
{if (root != NULL){btree_inorder_traversal (root->lchild);printf ("%d ", root->val);btree_inorder_traversal (root->rchild);}
}/********************************//**/
void
test_tree_append (void)
{BTreeNode *root = btree_node_new (50);btree_append_left (root, 40);btree_append_right (root, 60);btree_inorder_traversal (root);printf ("\n");btree_free (root);
}/**/
int
main (int argc, char *argv[])
{test_tree_append ();return 0;
}
/* --[.^.]-- */
编译运行,检测内存,效果如预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree
40 50 60
songvm@ubuntu:~/works/xdn/too$ valgrind --leak-check=yes ./btree
==3531== Memcheck, a memory error detector
==3531== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3531== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3531== Command: ./btree
==3531==
40 50 60
==3531==
==3531== HEAP SUMMARY:
==3531== in use at exit: 0 bytes in 0 blocks
==3531== total heap usage: 4 allocs, 4 frees, 1,096 bytes allocated
==3531==
==3531== All heap blocks were freed -- no leaks are possible
==3531==
==3531== For counts of detected and suppressed errors, rerun with: -v
==3531== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/too$
实现了中序遍历,同理还可以实现前序遍历(根左右)和后序遍历(左右根)
- 前序遍历prevorder_traversal,顺序:根->左->右
- 后序遍历postorder_traversal,顺序:左->右->根
- 另:追加未返回节点的指针,无法继续追加,需要改进!!!
代码如下:
/* filename: btree.c */
#include <stdio.h>
#include <stdlib.h>/* compile : gcc btree.c -o btree */
/* run : ./btree *//* define function pointer BTFunc for output */
typedef void (*BTFunc) (int val);/* define the BTreeNode datatype */
typedef struct _BTreeNode BTreeNode;
struct _BTreeNode {int val;BTreeNode *lchild, *rchild;
};/* create new BTreeNode */
BTreeNode *
btree_node_new (int val)
{BTreeNode *node = (BTreeNode*) malloc (sizeof(BTreeNode));node->val = val;node->lchild = NULL;node->rchild = NULL;return node;
}/* free a btree, every nodes in BTreeNode *root, recursion */
void
btree_free (BTreeNode *root)
{if (root != NULL){btree_free (root->lchild);btree_free (root->rchild);free (root);}
}/* append left child node to root with val */
BTreeNode*
btree_append_left (BTreeNode *root, int val)
{BTreeNode *node = btree_node_new (val);root->lchild = node;return node;
}/* append right child node to root with val*/
BTreeNode*
btree_append_right (BTreeNode *root, int val)
{BTreeNode *node = btree_node_new (val);root->rchild = node;return node;
}/* inorder traversal, left->root->right */
void
btree_inorder_traversal (BTreeNode *root)
{if (root != NULL){btree_inorder_traversal (root->lchild);printf ("%d ", root->val);btree_inorder_traversal (root->rchild);}
}/********************************//**/
void
test_tree_append (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (50);na = btree_append_left (root, 40);nb = btree_append_right (root, 60);btree_append_left (na, 20);btree_append_right (na, 30);btree_append_left (nb, 70);btree_append_right (nb, 80);btree_inorder_traversal (root);printf ("\n");btree_free (root);
}/**/
int
main (int argc, char *argv[])
{test_tree_append ();return 0;
}
/* --[.^.]-- */
编译运行,效果如预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree
20 40 30 50 70 60 80
songvm@ubuntu:~/works/xdn/too$ valgrind --leak-check=yes ./btree
==3541== Memcheck, a memory error detector
==3541== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3541== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3541== Command: ./btree
==3541==
20 40 30 50 70 60 80
==3541==
==3541== HEAP SUMMARY:
==3541== in use at exit: 0 bytes in 0 blocks
==3541== total heap usage: 8 allocs, 8 frees, 1,192 bytes allocated
==3541==
==3541== All heap blocks were freed -- no leaks are possible
==3541==
==3541== For counts of detected and suppressed errors, rerun with: -v
==3541== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/too$
测试中序遍历、前序遍历和后序遍历,运行结果如下,达到预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree
20 40 30 50 70 60 80
50 20 40 30 70 60 80
20 40 30 50 70 60 80
songvm@ubuntu:~/works/xdn/too$
这种显示为一行对调试来说并不直观,可以更直观一些
- 每行显示一个树节点,根据树的高度,循环输出空格,为函数传参数lv,初始值为0,每调用一次加1!!!
- 为函数传参数lr,用字符R或L来标出是左还是右,根据R或L输出字符<或>!!!
代码如下:
/**/
void
btree_mid_print_lrv (BTreeNode *root, int lv, char lr)
{if (root != NULL){btree_mid_print_lrv (root->lchild, lv + 1, 'L');for (int i = 0; i < lv; i++) printf (" ");if (lr == 'L') printf ("<");if (lr == 'R') printf (">");printf ("%d\n", root->val);btree_mid_print_lrv (root->rchild, lv + 1, 'R');}
}/**/
void
btree_mid_print (BTreeNode *root)
{btree_mid_print_lrv (root, 0, 'N');
}/********************************//**/
void
test_tree_append (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (50);na = btree_append_left (root, 40);nb = btree_append_right (root, 60);btree_append_left (na, 20);btree_append_right (na, 30);btree_append_left (nb, 70);btree_append_right (nb, 80);//btree_inorder_traversal (root); printf ("\n"); //OK!!1btree_mid_print (root);btree_free (root);
}
编译运行,达到预期,结果如下:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree<20<40>30
50<70>60>80
songvm@ubuntu:~/works/xdn/too$
上面显示的结果是不完整的,因为没有显示空节点!!!
- 在函数:btree_mid_print_lrv中的if结构下面加上else,用#代表空节点!
代码如下:
else{for (int i = 0; i < lv; i++) printf (" ");if (lr == 'L') printf ("<");if (lr == 'R') printf (">");printf ("#\n");}
编译运行,效果如预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree<#<20>#<40<#>30>#
50<#<70>#>60<#>80>#
songvm@ubuntu:~/works/xdn/too$
二叉树的查找功能search
- 按给定的值查找节点,btree_search函数
代码如下:
/* search val in BTreeNode root return node pointer */
BTreeNode *
btree_search (BTreeNode *root, int val)
{BTreeNode *node = NULL;if (root != NULL){if (root->val == val) return root;node = btree_search (root->lchild, val);if (node != NULL) return node;node = btree_search (root->rchild, val);}return node;
}/********************************//**/
void
test_tree_append (void)
{BTreeNode *na, *nb, *root, *tmp;root = btree_node_new (50);na = btree_append_left (root, 40);nb = btree_append_right (root, 60);btree_append_left (na, 20);btree_append_right (na, 30);btree_append_left (nb, 70);btree_append_right (nb, 80);//btree_inorder_traversal (root); printf ("\n"); //OK!!1//btree_mid_print (root);tmp = btree_search (root, 60);if (tmp != NULL)printf ("Found node : val ==> %d\n", tmp->val);elseprintf ("Not found node val == 60\n");tmp = btree_search (root, 65);if (tmp != NULL)printf ("Found node : val ==> %d\n", tmp->val);elseprintf ("Not found node val == 65\n");btree_free (root);
}
编译运行,结果如预期(60存在故找到,65不存在故找不到):
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree
Found node : val ==> 60
Not found node val == 65
songvm@ubuntu:~/works/xdn/too$
二叉树节点的删除remove
-
按给定值删除节点,就复杂了,首先用上面的查找方法,找到节点!
-
分以下几种情况:
-
1、叶子节点,左右子节点均为空,直接删除!
-
2、只有一个子节点的(左或右子节点),左右子节点有一个为空,删除后,子节点递补!
-
3、有两个子节点,左右子节点均不为空,以右子节点为主,向上递补!
-
4、根节点,有子节点,向上浮动值,删除最后一个子节点!
-
5、根节点,无子节点,不删除,留给编程者自己释放!
-
浮动调整函数 btree_adjust
-
移动节点函数 btree_aappend_node_toleft,有两个字节点的树节点被删除后,左子节点附加到右子节点的左子节点上!
-
删除节点同时指出该节点的父节点,是左子节点还是右子节点 btree_remove_bylr
-
删除节点函数 btree_remove,全树查找值为val的节点,找到后删除!!!
代码如下:
/* adjust data of tree node and free not inuse tree node */
static void
btree_adjust (BTreeNode *root)
{char lr = 'N';BTreeNode *pn = root, *node;if (root->rchild != NULL) { node = root->rchild; lr = 'R'; }else if (root->lchild != NULL) { node = root->lchild; lr = 'L'; }else{ return; } //*root = NULL; return; } //todoroot->val = node->val;while (node->rchild != NULL){BTreeNode *tmp = node->rchild;pn = node;node->val = tmp->val;node = tmp;}if (lr == 'R') pn->rchild = NULL;if (lr == 'L') pn->lchild = NULL;free (node);
}/* append node tmp to node root */
static void
btree_aappend_node_toleft (BTreeNode *root, BTreeNode *tmp)
{if (root->lchild == NULL){ root->lchild = tmp; return; }else if (root->rchild == NULL){ root->rchild = tmp; return; }elsebtree_append_node_toleft (root->lchild, tmp);
}/* remove BTreeNode by val on node, call with parent node */
int
btree_remove_bylr (BTreeNode *node, BTreeNode *parent, char lr, int val)
{if (node != NULL){if (node->val == val){if (node->lchild == NULL && node->rchild == NULL){if (parent != NULL){if (lr == 'L') parent->lchild = NULL;if (lr == 'R') parent->rchild = NULL;free (node);}else{printf ("Remove the root node is a foolish operate!\n");}return 1;}else if (node->lchild == NULL){BTreeNode *tmp = node->rchild;if (parent != NULL){if (lr == 'L') parent->lchild = tmp;if (lr == 'R') parent->rchild = tmp;free (node);}else{btree_adjust (node);}return 1;}else if (node->rchild == NULL){BTreeNode *tmp = node->lchild;if (parent != NULL){if (lr == 'L') parent->lchild = tmp;if (lr == 'R') parent->rchild = tmp;free (node);}else{btree_adjust (node);}return 1;}else{BTreeNode *tmp = node;BTreeNode *tmpx = node->lchild;BTreeNode *tmpy = node->rchild;if (parent != NULL){if (lr == 'L') parent->lchild = tmpy;if (lr == 'R') parent->rchild = tmpy;free (tmp);}else{btree_adjust (node);return 1;}btree_append_node_toleft (tmpy, tmpx);return 1;}}else{int ret;ret = btree_remove_bylr (node->lchild, node, 'L', val);if (ret == 0)ret = btree_remove_bylr (node->rchild, node, 'R', val);return ret;}}return 0;
}/* remove node by val in root if ok return 1 else return 0 */
int
btree_remove (BTreeNode *root, int val)
{return btree_remove_bylr (root, NULL, 'N', val);
}
- 测试代码如下:
/**/
void
test_tree_remove_leaf (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (5);na = btree_append_left (root, 3);nb = btree_append_right (root, 7);btree_append_left (na, 1);btree_append_right (na, 2);btree_append_left (nb, 6);btree_append_right (nb, 8);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 1);btree_remove (root, 2);btree_remove (root, 6);btree_remove (root, 8);btree_mid_print (root);printf ("--------------------\n");btree_free (root);
}
编译运行,效果如下,删除全部子节点,达到预期!!!
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree<#<1>#<3<#>2>#
5<#<6>#>7<#>8>#
--------------------<#<3>#
5<#>7>#
--------------------
songvm@ubuntu:~/works/xdn/too$
测试删除有两个子结点的结点
代码如下:
/**/
void
test_tree_remove_node (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (5);na = btree_append_left (root, 3);nb = btree_append_right (root, 7);btree_append_left (na, 1);btree_append_right (na, 2);btree_append_left (nb, 6);btree_append_right (nb, 8);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 3);btree_remove (root, 7);btree_mid_print (root);printf ("--------------------\n");btree_free (root);
}
编译运行,结果如下,达到预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree<#<1>#<3<#>2>#
5<#<6>#>7<#>8>#
--------------------<#<1>#<2>#
5<#<6>#>8>#
--------------------
songvm@ubuntu:~/works/xdn/too$
测试删除有一个子节点的节点
代码如下:
/**/
void
test_tree_remove_node_mid (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (5);na = btree_append_left (root, 3);nb = btree_append_right (root, 7);btree_append_left (na, 1);btree_append_right (na, 2);btree_append_left (nb, 6);btree_append_right (nb, 8);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 3);btree_remove (root, 7);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 2);btree_remove (root, 8);btree_mid_print (root);printf ("--------------------\n");btree_free (root);
}
编译运行,结果如下,达到预期:
songvm@ubuntu:~/works/xdn/too$ gcc btree.c -o btree
songvm@ubuntu:~/works/xdn/too$ ./btree<#<1>#<3<#>2>#
5<#<6>#>7<#>8>#
--------------------<#<1>#<2>#
5<#<6>#>8>#
--------------------<#<1>#
5<#>6>#
--------------------
songvm@ubuntu:~/works/xdn/too$
- 个人认为删除根结点是愚蠢的,因为最后要释放掉,这会造成两次释放同一个指针的错误!!!
完整代码如下:
/* filename: btree.c */
#include <stdio.h>
#include <stdlib.h>/* compile : gcc btree.c -o btree */
/* run : ./btree *//* define function pointer BTFunc for output */
typedef void (*BTFunc) (int val);/* define the BTreeNode datatype */
typedef struct _BTreeNode BTreeNode;
struct _BTreeNode {int val;BTreeNode *lchild, *rchild;
};/* create new BTreeNode */
BTreeNode *
btree_node_new (int val)
{BTreeNode *node = (BTreeNode*) malloc (sizeof(BTreeNode));node->val = val;node->lchild = NULL;node->rchild = NULL;return node;
}/* free a btree, every nodes in BTreeNode *root, recursion */
void
btree_free (BTreeNode *root)
{if (root != NULL){btree_free (root->lchild);btree_free (root->rchild);free (root);}
}/* append left child node to root with val */
BTreeNode*
btree_append_left (BTreeNode *root, int val)
{BTreeNode *node = btree_node_new (val);root->lchild = node;return node;
}/* append right child node to root with val*/
BTreeNode*
btree_append_right (BTreeNode *root, int val)
{BTreeNode *node = btree_node_new (val);root->rchild = node;return node;
}/* inorder traversal, left->root->right */
void
btree_inorder_traversal (BTreeNode *root)
{if (root != NULL){btree_inorder_traversal (root->lchild);printf ("%d ", root->val);btree_inorder_traversal (root->rchild);}
}/* prev order traversal, root->left->right */
void
btree_prevorder_traversal (BTreeNode *root)
{if (root != NULL){printf ("%d ", root->val);btree_inorder_traversal (root->lchild);btree_inorder_traversal (root->rchild);}
}/* post order traversal, left->right->root */
void
btree_postorder_traversal (BTreeNode *root)
{if (root != NULL){btree_inorder_traversal (root->lchild);printf ("%d ", root->val);btree_inorder_traversal (root->rchild);}
}/**/
void
btree_mid_print_lrv (BTreeNode *root, int lv, char lr)
{if (root != NULL){btree_mid_print_lrv (root->lchild, lv + 1, 'L');for (int i = 0; i < lv; i++) printf (" ");if (lr == 'L') printf ("<");if (lr == 'R') printf (">");printf ("%d\n", root->val);btree_mid_print_lrv (root->rchild, lv + 1, 'R');}else{for (int i = 0; i < lv; i++) printf (" ");if (lr == 'L') printf ("<");if (lr == 'R') printf (">");printf ("#\n");}
}/**/
void
btree_mid_print (BTreeNode *root)
{btree_mid_print_lrv (root, 0, 'N');
}/* search val in BTreeNode root return node pointer */
BTreeNode *
btree_search (BTreeNode *root, int val)
{BTreeNode *node = NULL;if (root != NULL){if (root->val == val) return root;node = btree_search (root->lchild, val);if (node != NULL) return node;node = btree_search (root->rchild, val);}return node;
}/* adjust data of tree node and free not inuse tree node */
static void
btree_adjust (BTreeNode *root)
{char lr = 'N';BTreeNode *pn = root, *node;if (root->rchild != NULL) { node = root->rchild; lr = 'R'; }else if (root->lchild != NULL) { node = root->lchild; lr = 'L'; }else{ return; } //*root = NULL; return; } //todoroot->val = node->val;while (node->rchild != NULL){BTreeNode *tmp = node->rchild;pn = node;node->val = tmp->val;node = tmp;}if (lr == 'R') pn->rchild = NULL;if (lr == 'L') pn->lchild = NULL;free (node);
}/* append node tmp to node root */
static void
btree_append_node_toleft (BTreeNode *root, BTreeNode *tmp)
{if (root->lchild == NULL){ root->lchild = tmp; return; }else if (root->rchild == NULL){ root->rchild = tmp; return; }elsebtree_append_node_toleft (root->lchild, tmp);
}/* remove BTreeNode by val on node, call with parent node */
int
btree_remove_bylr (BTreeNode *node, BTreeNode *parent, char lr, int val)
{if (node != NULL){if (node->val == val){if (node->lchild == NULL && node->rchild == NULL){if (parent != NULL){if (lr == 'L') parent->lchild = NULL;if (lr == 'R') parent->rchild = NULL;free (node);}else{printf ("Remove the root node is a foolish operate!\n");}return 1;}else if (node->lchild == NULL){BTreeNode *tmp = node->rchild;if (parent != NULL){if (lr == 'L') parent->lchild = tmp;if (lr == 'R') parent->rchild = tmp;free (node);}else{btree_adjust (node);}return 1;}else if (node->rchild == NULL){BTreeNode *tmp = node->lchild;if (parent != NULL){if (lr == 'L') parent->lchild = tmp;if (lr == 'R') parent->rchild = tmp;free (node);}else{btree_adjust (node);}return 1;}else{BTreeNode *tmp = node;BTreeNode *tmpx = node->lchild;BTreeNode *tmpy = node->rchild;if (parent != NULL){if (lr == 'L') parent->lchild = tmpy;if (lr == 'R') parent->rchild = tmpy;free (tmp);}else{btree_adjust (node);return 1;}btree_append_node_toleft (tmpy, tmpx);return 1;}}else{int ret;ret = btree_remove_bylr (node->lchild, node, 'L', val);if (ret == 0)ret = btree_remove_bylr (node->rchild, node, 'R', val);return ret;}}return 0;
}/* remove node by val in root if ok return 1 else return 0 */
int
btree_remove (BTreeNode *root, int val)
{return btree_remove_bylr (root, NULL, 'N', val);
}/********************************//**/
void
test_tree_append (void)
{BTreeNode *na, *nb, *root, *tmp;root = btree_node_new (50);na = btree_append_left (root, 40);nb = btree_append_right (root, 60);btree_append_left (na, 20);btree_append_right (na, 30);btree_append_left (nb, 70);btree_append_right (nb, 80);btree_inorder_traversal (root); printf ("\n"); //OK!!1btree_prevorder_traversal (root); printf ("\n"); //OK!!1btree_postorder_traversal (root); printf ("\n"); //OK!!1//btree_mid_print (root);/*tmp = btree_search (root, 60);if (tmp != NULL)printf ("Found node : val ==> %d\n", tmp->val);elseprintf ("Not found node val == 60\n");tmp = btree_search (root, 65);if (tmp != NULL)printf ("Found node : val ==> %d\n", tmp->val);elseprintf ("Not found node val == 65\n");*/btree_free (root);
}/**/
void
test_tree_remove_leaf (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (5);na = btree_append_left (root, 3);nb = btree_append_right (root, 7);btree_append_left (na, 1);btree_append_right (na, 2);btree_append_left (nb, 6);btree_append_right (nb, 8);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 1);btree_remove (root, 2);btree_remove (root, 6);btree_remove (root, 8);btree_mid_print (root);printf ("--------------------\n");btree_free (root);
}/**/
void
test_tree_remove_node (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (5);na = btree_append_left (root, 3);nb = btree_append_right (root, 7);btree_append_left (na, 1);btree_append_right (na, 2);btree_append_left (nb, 6);btree_append_right (nb, 8);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 3);btree_remove (root, 7);btree_mid_print (root);printf ("--------------------\n");btree_free (root);
}/**/
void
test_tree_remove_node_mid (void)
{BTreeNode *na, *nb, *root;root = btree_node_new (5);na = btree_append_left (root, 3);nb = btree_append_right (root, 7);btree_append_left (na, 1);btree_append_right (na, 2);btree_append_left (nb, 6);btree_append_right (nb, 8);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 3);btree_remove (root, 7);btree_mid_print (root);printf ("--------------------\n");btree_remove (root, 2);btree_remove (root, 8);btree_mid_print (root);printf ("--------------------\n");btree_free (root);
}/**/
int
main (int argc, char *argv[])
{test_tree_append ();//test_tree_remove_leaf ();//test_tree_remove_node ();//test_tree_remove_node_mid ();return 0;
}
/* --[.^.]-- */
- 下一步研究将这个树结构改造成可以存贮多种数据类型的数据结构!!!