二叉树的创建及其遍历

来源:互联网 发布:手机知乎怎么回答问题 编辑:程序博客网 时间:2024/05/19 22:02

https://www.github.com/wangzhijun_0224/AlgorithmStudy.git

.h文件:

#ifndef _DS_CHARPTER05_H_#define _DS_CHARPTER05_H_/*************************************************************************************************/// 二叉树的结点抽象#define BTREE_HAVE_PARENT1typedef struct treenode* tlink;tlink  tlink_new_tnode(int item_size, void* pitem);        // 获取一个节点,并将pitem所指向的item拷贝到节点中void   tlink_get_item(tlink p, int item_size, void *pitem);// 获取节点的item数据void   tlink_insert_left(tlink p, tlink newnode);// 将newnode插入到p的左儿子上void   tlink_insert_right(tlink p, tlink newnode);// 将newnode插入到p的右儿子上void   tlink_insert_both(tlink p, tlink left, tlink right);#if BTREE_HAVE_PARENTtlink  tlink_get_parent(tlink p);#endiftlink  tlink_get_lchild(tlink p);tlink  tlink_get_rchild(tlink p);tlink* tlink_get_lchild_addr(tlink p);tlink* tlink_get_rchild_addr(tlink p);/*************************************************************************************************/// 二叉树抽象typedef struct binary_tree* btree;btree btree_open(int item_size);// 创建一个空树void btree_close(btree bt);int btree_is_empty(btree bt);// 判断树是否为空void btree_make_btree(btree bt, void *pitem, void* penditem);void btree_get_item(btree bt, tlink root, void *pitem);// 获取以root为根结点的根节点数据tlink btree_get_root(btree bt);#if BTREE_HAVE_PARENTtlink btree_get_parent(btree bt, tlink root);// 获取root节点的父节点#endiftlink btree_get_lchild(btree bt, tlink root);// 获取以root为根节点的左子树tlink btree_get_rchild(btree bt, tlink root);// 获取以root为根节点的右子树int btree_preorder_recursion(btree bt, void* pitem);     // 递归版前序遍历树,结果存放在pitem数组中,返回值为树中元素个数int btree_inorder_recursion(btree bt, void* pitem);      // 递归版中序遍历树,结果存放在pitem数组中,返回值为树中元素个数int btree_postorder_recursion(btree bt, void* pitem);    // 递归版后序遍历树,结果存放在pitem数组中,返回值为树中元素个数int btree_preorder_norecursion(btree bt, void* pitem);   // 非递归版前序遍历树,结果存放在pitem数组中,返回值为树中元素个数int btree_preorder_norecursion2(btree bt, void* pitem);  // 非递归版前序遍历树,另一种方法int btree_inorder_norecursion(btree bt, void* pitem);    // 非递归版中序遍历树,结果存放在pitem数组中,返回值为树中元素个数int btree_postorder_norecursion(btree bt, void* pitem);  // 非递归版后序遍历树,结果存放在pitem数组中,返回值为树中元素个数int btree_postorder_norecursion2(btree bt, void* pitem); // 非递归版后序遍历树,另一种方法int btree_levelorder(btree bt, void* pitem);             // 层序遍历树,同层从左至右int btree_levelorderR(btree bt, void* pitem);            // 层序遍历树,同层从右至左#endif


.c文件:

#include "DS_charpter04.h"  // stack, queue#include "DS_charpter05.h"#include <stdlib.h>#include <assert.h>#include <string.h>/*************************************************************************************************//***********************************************************************************单链表节点抽象***********************************************************************************/// 不完全类型,申请节点的空间是需要加上item的大小struct treenode{ #if BTREE_HAVE_PARENTtlink parent;#endiftlink left, right; };tlink  tlink_new_tnode(int item_size, void* pitem){tlink newnode = (tlink)malloc(sizeof(*newnode) + item_size);void* dst;if (NULL != newnode){#if BTREE_HAVE_PARENTnewnode->parent = NULL;#endifnewnode->left = newnode->right = NULL;dst = (char *)newnode + sizeof(*newnode);memcpy(dst, pitem, item_size);}return newnode;}void   tlink_get_item(tlink p, int item_size, void *pitem){assert(NULL != p);assert(NULL != pitem);void *src = (char *)p + sizeof(*p);memcpy(pitem, src, item_size);}void   tlink_insert_left(tlink p, tlink newnode){#if BTREE_HAVE_PARENTif (newnode != NULL) newnode->parent = p;#endifp->left = newnode;}void   tlink_insert_right(tlink p, tlink newnode){#if BTREE_HAVE_PARENTif (newnode != NULL) newnode->parent = p;#endifp->right = newnode;}void tlink_insert_both(tlink p, tlink left, tlink right){#if BTREE_HAVE_PARENTif (left != NULL)left->parent = p;if (right != NULL)right->parent = p;#endifp->left = left;p->right = right;}#if BTREE_HAVE_PARENTtlink  tlink_get_parent(tlink p){return p->parent;}#endiftlink  tlink_get_lchild(tlink p){return p->left;}tlink  tlink_get_rchild(tlink p){return p->right;}tlink* tlink_get_lchild_addr(tlink p){return &(p->left);}tlink* tlink_get_rchild_addr(tlink p){return &(p->right);}/*************************************************************************************************/// 二叉树抽象struct binary_tree{tlink root;int item_size;};btree btree_open(int item_size){assert(item_size > 0);btree bt = (btree)malloc(sizeof(*bt));if (NULL == bt) return bt;bt->item_size = item_size;bt->root = NULL;return bt;}static void btree_del(tlink root){if (NULL != root){btree_del(root->left);btree_del(root->right);free(root);}}void btree_close(btree bt){btree_del(bt->root);free(bt);}int btree_is_empty(btree bt){assert(NULL != bt);return (bt->root == NULL);}#if BTREE_HAVE_PARENTstatic int btree_create_p(tlink parent, tlink *root, void* pitem, int* pindex, int item_size, void* enditem){void* pcuritem = (char*)pitem + (*pindex)*item_size;if (0 == memcmp(pcuritem, enditem, item_size)){return 0;}*root = tlink_new_tnode(item_size, pcuritem);if (NULL == *root)  return 0;(*root)->parent = parent;(*pindex)++;btree_create_p(*root, tlink_get_lchild_addr(*root), pitem, pindex, item_size, enditem);(*pindex)++;btree_create_p(*root, tlink_get_rchild_addr(*root), pitem, pindex, item_size, enditem);return 1;}#elsestatic int btree_create(tlink *root, void* pitem, int* pindex, int item_size, void* enditem){void* pcuritem = (char*)pitem + (*pindex)*item_size;if (0 == memcmp(pcuritem, enditem, item_size)){return 0;}*root = tlink_new_tnode(item_size, pcuritem);if (NULL == *root)  return 0;(*pindex)++;btree_create(tlink_get_lchild_addr(*root), pitem, pindex, item_size, enditem);(*pindex)++;btree_create(tlink_get_rchild_addr(*root), pitem, pindex, item_size, enditem);return 1;}#endifvoid btree_make_btree(btree bt, void *pitem, void* penditem){int index = 0;#if BTREE_HAVE_PARENTbtree_create_p(NULL, &(bt->root), pitem, &index, bt->item_size, penditem); // root's parent is NULL#elsebtree_create(&(bt->root), pitem, &index, bt->item_size, penditem);#endif}void btree_get_item(btree bt, tlink root, void *pitem){assert(bt != NULL);assert(root != NULL);assert(pitem != NULL);tlink_get_item(root, bt->item_size, pitem);}tlink btree_get_root(btree bt){return bt->root;}#if BTREE_HAVE_PARENTtlink btree_get_parent(btree bt, tlink root){if (NULL == root)return NULL;elsereturn tlink_get_parent(root);}#endiftlink btree_get_lchild(btree bt, tlink root){if (NULL == root)return NULL;elsereturn tlink_get_lchild(root);}tlink btree_get_rchild(btree bt, tlink root){if (NULL == root)return NULL;elsereturn tlink_get_rchild(root);}/*************************************************************************************************//***********************************************************************************递归版前序遍历: 根节点-左孩子-右孩子的顺序遍历***********************************************************************************/static void preorder_recursion(btree bt, tlink root, void* pitem, int* pindex){char *dst;if (NULL != root){dst = (char*)pitem + (*pindex)*sizeof(char);btree_get_item(bt, root, dst);(*pindex)++;preorder_recursion(bt, btree_get_lchild(bt, root), pitem, pindex);preorder_recursion(bt, btree_get_rchild(bt, root), pitem, pindex);}}/***********************************************************************************递归版中序遍历: 左孩子-根节点-右孩子***********************************************************************************/static void inorder_recursion(btree bt, tlink root, void* pitem, int* pindex){char *dst;if (NULL != root){inorder_recursion(bt, btree_get_lchild(bt, root), pitem, pindex);dst = (char*)pitem + (*pindex)*sizeof(char);btree_get_item(bt, root, dst);(*pindex)++;inorder_recursion(bt, btree_get_rchild(bt, root), pitem, pindex);}}/***********************************************************************************递归版后序遍历: 左孩子-右孩子-根节点***********************************************************************************/static void postorder_recursion(btree bt, tlink root, void* pitem, int* pindex){char *dst;if (NULL != root){postorder_recursion(bt, btree_get_lchild(bt, root), pitem, pindex);postorder_recursion(bt, btree_get_rchild(bt, root), pitem, pindex);dst = (char*)pitem + (*pindex)*sizeof(char);btree_get_item(bt, root, dst);(*pindex)++;}}int btree_preorder_recursion(btree bt, void* pitem){tlink root = NULL;int index = 0;assert(NULL != bt);assert(NULL != pitem);root = btree_get_root(bt);preorder_recursion(bt, root, pitem, &index);return index;}int btree_inorder_recursion(btree bt, void* pitem){tlink root = NULL;int index = 0;assert(NULL != bt);assert(NULL != pitem);root = btree_get_root(bt);inorder_recursion(bt, root, pitem, &index);return index;}int btree_postorder_recursion(btree bt, void* pitem){tlink root = NULL;int index = 0;assert(NULL != bt);assert(NULL != pitem);root = btree_get_root(bt);postorder_recursion(bt, root, pitem, &index);return index;}/*************************************************************************************************/#if (!BTREE_HAVE_PARENT)/***********************************************************************************非递归版前序遍历:根据前序遍历访问的顺序,优先访问根节点,然后再分别访问左孩子和右孩子,即对于任一节点,其可看做是根节点,因此可直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问完其左子树时,再访问它的右子树。对于任一结点P:1)访问结点P,并将结点P入栈;2)判断结点P的左孩子是否为空,若为空,则从栈中取出栈顶元素,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;3)直到栈为空,则遍历结束。***********************************************************************************/int btree_preorder_norecursion(btree bt, void* pitem){tlink root = btree_get_root(bt);char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);stack_slist stk = stack_slist_open(sizeof(root));while (1){while (NULL != root){dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, root, dst);index++;stack_slist_insert(stk, &root);root = btree_get_lchild(bt, root);}if (0 == stack_slist_del(stk, &root)) break;    // 栈为空 root = btree_get_rchild(bt, root);}stack_slist_close(stk);return index;}#else/***********************************************************************************带有parent属性的前序非递归遍历:对于任一结点root:1)访问结点root;2)判断root的左孩子是否为空,若不为空,则将root的左孩子设置为root,循环至1);若为空,则转至3);3)取root的右孩子,如果root的右孩子不为空,则将root的右孩子设置为root,循环至1);  若为空,则沿root的parent往上搜索,直到parent为空(则遍历结束)或找到一个parent的右孩子不为root为止,  将此parent的右孩子设置为root,循环至1)***********************************************************************************/int btree_preorder_norecursion(btree bt, void* pitem){tlink root, left, right, parent;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);for (root = btree_get_root(bt); root != NULL; ){        while (1){dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, root, dst);index++;left = btree_get_lchild(bt, root);if (NULL == left)break;elseroot = left;}right = btree_get_rchild(bt, root);if (NULL == right)// 右子树遍历完成{// 沿二叉树往上搜索,直到parent为空或找到一个parent的右节点不为root为止parent = tlink_get_parent(root);while (NULL != parent && root == btree_get_rchild(bt, parent)){root = parent;parent = tlink_get_parent(parent);}if (NULL != parent) root = btree_get_rchild(bt, parent);else break;}else// 有右子树,遍历右子树{root = right;}}return index;}#endif/***********************************************************************************非递归版前序遍历2:***********************************************************************************/int btree_preorder_norecursion2(btree bt, void* pitem){tlink root = btree_get_root(bt), tmplink;stack_slist stk;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);if (NULL == root)   return 0; // 空节点不入栈stk = stack_slist_open(sizeof(root));stack_slist_insert(stk, &root);while (1){if (0 == stack_slist_top(stk, &root))    break;dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, root, dst);index++;stack_slist_pop(stk);tmplink = btree_get_rchild(bt, root);if (NULL != tmplink) stack_slist_insert(stk, &tmplink);tmplink = btree_get_lchild(bt, root);if (NULL != tmplink) stack_slist_insert(stk, &tmplink);}stack_slist_close(stk);return index;}#if (!BTREE_HAVE_PARENT)/***********************************************************************************非递归版中序遍历:根据中序遍历的顺序,对于任一节点,优先访问其左孩子,而左孩子节点又可看做根节点,然后继续访问其左孩子节点,直到遇到左孩子为空的节点才进行访问,然后按相同的规则访问其右子树。对于任一结点P:1)若结点P的左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后循环当前判断;若P的左孩子为空,则从栈中取出栈顶元素,访问栈顶节点,然后将当前的P设为栈顶节点的右孩子;3)直到栈为空,则遍历结束。***********************************************************************************/int btree_inorder_norecursion(btree bt, void* pitem){tlink tmplink;stack_slist stk;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);tmplink = btree_get_root(bt);stk = stack_slist_open(sizeof(tmplink));while (1){while (tmplink != NULL){stack_slist_insert(stk, &tmplink);tmplink = btree_get_lchild(bt, tmplink);}if (0 == stack_slist_del(stk, &tmplink)) break;dst = (char*)pitem + index*sizeof(char);index++;btree_get_item(bt, tmplink, dst);tmplink = btree_get_rchild(bt, tmplink);}stack_slist_close(stk);return index;}#else/***********************************************************************************带有parent属性的中序非递归遍历:对于任一结点root:1)判断root的左孩子是否为空,若不为空,则将root的左孩子设置为root,循环本步骤;  若为空,则转至2);2)访问节点root,然后判断root的右孩子是否为空,若不为空,则将root的右孩子设置为root,循环至1);  若为空,则沿root的parent往上搜索,直到parent为空(则遍历结束)或找到一个parent的右孩子不为root为止,  此时先访问parent的值,再将此parent的右孩子设置为root,循环至1)***********************************************************************************/int btree_inorder_norecursion(btree bt, void* pitem){tlink root, parent, left, right;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);root = btree_get_root(bt);while (NULL != root){while(1){left = btree_get_lchild(bt, root);if (NULL == left)break;// 左子树遍历完成else root = left;}dst = (char*)pitem + index*sizeof(char);index++;btree_get_item(bt, root, dst);right = btree_get_rchild(bt, root);if (NULL == right){parent = tlink_get_parent(root);while (NULL != parent && root == btree_get_rchild(bt, parent)){root = parent;parent = tlink_get_parent(parent);}if (NULL != parent) {// 遍历p的右子树之前,先访问pdst = (char*)pitem + index*sizeof(char);index++;btree_get_item(bt, parent, dst);root = btree_get_rchild(bt, parent);}else break;}else{root = right;}}return index;}#endif#if (!BTREE_HAVE_PARENT)/***********************************************************************************非递归版后序遍历1:思路: 对于任一节点P,将其入栈,然后沿其左子树一直往下搜索,直到搜到到美欧左孩子的节点,此时该节点出现在栈顶,但此时不能将其出栈并访问,因其右孩子还未被访问。所以,接下来按相同的规则对其右子树进行处理,当访问完其右孩子时,该节点又出现在栈顶,此时可以将其出栈并访问。即:每个节点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此,多设置一个变量标识该节点是否第一次出现在栈顶。***********************************************************************************/typedef struct pstorder_stack_item{tlink link;int   flag; // 1: 第一次出现在栈顶 0:不是第一次出现在栈顶}pstorder_stack_item;int btree_postorder_norecursion(btree bt, void* pitem){tlink root = btree_get_root(bt);pstorder_stack_item stk_item;stack_slist stk;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);stk = stack_slist_open(sizeof(stk_item));while (1){while (root != NULL){stk_item.flag = 1;stk_item.link = root;stack_slist_insert(stk, &stk_item);root = btree_get_lchild(bt, root);}if (0 == stack_slist_del(stk, &stk_item)) break;if (1 == stk_item.flag) // 第一次在栈顶{stk_item.flag = 0;stack_slist_insert(stk, &stk_item);root = btree_get_rchild(bt, stk_item.link); // 处理右子树}else   // 第二次在栈顶{dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, stk_item.link, dst);index++;root = NULL;}}stack_slist_close(stk);return index;}#else/***********************************************************************************带有parent属性的后序非递归遍历:对于任一结点root:1)判断root的左孩子是否为空,若不为空,则将root的左孩子设置为root,循环本步骤;  若为空,则转至2);2)然后判断root的右孩子是否为空,若不为空,则将root的右孩子设置为root,循环至1);  若为空,先访问root的值,再沿root的parent往上搜索:    若root为parent的右节点,则访问parent节点并继续向上搜索;  若搜索完成后,parent为空,则遍历结束;否则,将root设置为parent的右节点,循环至1);***********************************************************************************/int btree_postorder_norecursion(btree bt, void* pitem){tlink root, parent, left, right;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);root = btree_get_root(bt);while (NULL != root){while(1){left = btree_get_lchild(bt, root);if (NULL == left)break;// 左子树遍历完成else root = left;}right = btree_get_rchild(bt, root);if (NULL == right){dst = (char*)pitem + index*sizeof(char);index++;btree_get_item(bt, root, dst);parent = tlink_get_parent(root);while (NULL != parent && root == btree_get_rchild(bt, parent)){dst = (char*)pitem + index*sizeof(char);index++;btree_get_item(bt, parent, dst);root = parent;parent = tlink_get_parent(parent);}if (NULL != parent) {root = btree_get_rchild(bt, parent);}else break;}else{root = right;}}return index;}#endif/***********************************************************************************非递归版后序遍历2:思路:要保证根节点在左孩子和右孩子访问之后才能访问,因此对于任一节点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该节点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根节点前面被访问。***********************************************************************************/int btree_postorder_norecursion2(btree bt, void* pitem){tlink root = btree_get_root(bt), tmplink;tlink pre = NULL;stack_slist stk;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);if (NULL == root)   return 0;stk = stack_slist_open(sizeof(root));stack_slist_insert(stk, &root);while (1){if (0 == stack_slist_top(stk, &root))    break;if ((NULL == btree_get_lchild(bt, root) && NULL == btree_get_rchild(bt, root))|| (NULL != pre && (pre == btree_get_lchild(bt, root) || pre == btree_get_rchild(bt, root)))){dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, root, dst);index++;stack_slist_pop(stk);pre = root;}else{tmplink = btree_get_rchild(bt, root);if (NULL != tmplink) stack_slist_insert(stk, &tmplink);tmplink = btree_get_lchild(bt, root);if (NULL != tmplink) stack_slist_insert(stk, &tmplink);}}stack_slist_close(stk);return index;}/***********************************************************************************层序遍历二叉树:一层一层从左向右遍历***********************************************************************************/int btree_levelorder(btree bt, void* pitem){queue_slist qe;tlink root = btree_get_root(bt), tmplink;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);if (NULL == root)   return 0;qe = queue_slist_open(sizeof(root));queue_slist_insert(qe, &root);while (1){if (0 == queue_slist_del(qe, &root))    break;dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, root, dst);index++;tmplink = btree_get_lchild(bt, root);if (NULL != tmplink) queue_slist_insert(qe, &tmplink);tmplink = btree_get_rchild(bt, root);if (NULL != tmplink) queue_slist_insert(qe, &tmplink);}queue_slist_close(qe);return index;}/***********************************************************************************层序遍历二叉树:一层一层从右向左遍历***********************************************************************************/int btree_levelorderR(btree bt, void* pitem){queue_slist qe;tlink root = btree_get_root(bt), tmplink;char* dst;int index = 0;assert(NULL != bt);assert(NULL != pitem);if (NULL == root)   return 0;qe = queue_slist_open(sizeof(root));queue_slist_insert(qe, &root);while (1){if (0 == queue_slist_del(qe, &root))    break;dst = (char*)pitem + index*sizeof(char);btree_get_item(bt, root, dst);index++;tmplink = btree_get_rchild(bt, root);if (NULL != tmplink) queue_slist_insert(qe, &tmplink);tmplink = btree_get_lchild(bt, root);if (NULL != tmplink) queue_slist_insert(qe, &tmplink);}queue_slist_close(qe);return index;}


test.c:

#include "DS_charpter05_test.h"#include "DS_charpter05.h"static void create_btree_test(void){/*树:    A  /   \ B      C/ \    / \     D   E  F   G    / \   H   I*/char str[] = { 'A', 'B', 'D', 'H', '\0', '\0', 'I', '\0', '\0', 'E','\0', '\0', 'C', 'F', '\0', '\0', 'G', '\0', '\0' };char end_item = '\0';btree bt = btree_open(sizeof(char));btree_make_btree(bt, str, &end_item);tlink root = btree_get_root(bt);char ch;btree_get_item(bt, root, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[0], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(NULL, btree_get_parent(bt, root));#endiftlink left, right;left = btree_get_lchild(bt, root);btree_get_item(bt, left, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[1], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, left));#endifright = btree_get_rchild(bt, root);btree_get_item(bt, right, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[12], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, right));#endifroot = right;tlink tmp = btree_get_lchild(bt, root);btree_get_item(bt, tmp, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[13], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, tmp));#endiftmp = btree_get_rchild(bt, root);btree_get_item(bt, tmp, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[16], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, tmp));#endifroot = left;left = btree_get_lchild(bt, root);btree_get_item(bt, left, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[2], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, left));#endifright = btree_get_rchild(bt, root);btree_get_item(bt, right, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[9], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, right));#endifroot = left;left = btree_get_lchild(bt, root);btree_get_item(bt, left, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[3], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, left));#endifright = btree_get_rchild(bt, root);btree_get_item(bt, right, &ch);CU_ASSERT_PTR_DATA_EQUAL(&ch, &str[6], sizeof(ch));#if BTREE_HAVE_PARENTCU_ASSERT_EQUAL(root, btree_get_parent(bt, right));#endifbtree_close(bt);}/*递归版遍历函数测试*/static void btree_order_test1(void){/*树:   +  / \ *   E/ \     *   D    / \   /    C  / \A   B*/char str[] = { '+', '*', '*', '/', 'A', '\0', '\0', 'B', '\0', '\0','C', '\0', '\0', 'D', '\0', '\0', 'E', '\0', '\0' };char end_item = '\0';char str_rlt[sizeof(str) / sizeof(str[0])];btree bt = btree_open(sizeof(char));btree_make_btree(bt, str, &end_item);int index = 0;index = btree_preorder_recursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("+**/ABCDE", str_rlt, strlen("+**/ABCDE"));index = btree_inorder_recursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("A/B*C*D+E", str_rlt, strlen("A/B*C*D+E"));index = btree_postorder_recursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("AB/C*D*E+", str_rlt, strlen("AB/C*D*E+"));btree_close(bt);}/*非递归版遍历函数测试*/static void btree_order_test2(void){/*树:+/ \*   E/ \*   D/ \/    C/ \A   B*/char str[] = { '+', '*', '*', '/', 'A', '\0', '\0', 'B', '\0', '\0','C', '\0', '\0', 'D', '\0', '\0', 'E', '\0', '\0' };char end_item = '\0';char str_rlt[sizeof(str) / sizeof(str[0])];btree bt = btree_open(sizeof(char));btree_make_btree(bt, str, &end_item);int index = 0;index = btree_preorder_norecursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("+**/ABCDE", str_rlt, strlen("+**/ABCDE"));index = btree_preorder_norecursion2(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("+**/ABCDE", str_rlt, strlen("+**/ABCDE"));index = btree_inorder_norecursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("A/B*C*D+E", str_rlt, strlen("A/B*C*D+E"));index = btree_postorder_norecursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("AB/C*D*E+", str_rlt, strlen("AB/C*D*E+"));index = btree_postorder_norecursion2(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("AB/C*D*E+", str_rlt, strlen("AB/C*D*E+"));index = btree_levelorder(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("+*E*D/CAB", str_rlt, strlen("+*E*D/CAB"));index = btree_levelorderR(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("+E*D*C/BA", str_rlt, strlen("+E*D*C/BA"));btree_close(bt);}/*非递归版遍历函数测试*/static void btree_order_test3(void){/*树:A/   \B      C/ \    / \D   E  F   G/ \H   I*/char str[] = { 'A', 'B', 'D', 'H', '\0', '\0', 'I', '\0', '\0', 'E','\0', '\0', 'C', 'F', '\0', '\0', 'G', '\0', '\0' };char str_rlt[sizeof(str) / sizeof(str[0])];char end_item = '\0';btree bt = btree_open(sizeof(char));btree_make_btree(bt, str, &end_item);int index = 0;index = btree_preorder_norecursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("ABDHIECFG", str_rlt, strlen("ABDHIECFG"));index = btree_preorder_norecursion2(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("ABDHIECFG", str_rlt, strlen("ABDHIECFG"));index = btree_inorder_norecursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("HDIBEAFCG", str_rlt, strlen("HDIBEAFCG"));index = btree_postorder_norecursion(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("HIDEBFGCA", str_rlt, strlen("HIDEBFGCA"));index = btree_postorder_norecursion2(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("HIDEBFGCA", str_rlt, strlen("HIDEBFGCA"));index = btree_levelorder(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("ABCDEFGHI", str_rlt, strlen("ABCDEFGHI"));index = btree_levelorderR(bt, str_rlt);CU_ASSERT_EQUAL(index, 9);CU_ASSERT_PTR_DATA_EQUAL("ACBGFEDIH", str_rlt, strlen("ACBGFEDIH"));btree_close(bt);}/**********************************************************************************************************************************************************************/CU_TestInfo tests_datasture_charpter05[] = {{ "create_btree_test", create_btree_test },{ "btree_order_test1", btree_order_test1 },{ "btree_order_test2", btree_order_test2 },{ "btree_order_test3", btree_order_test3 },CU_TEST_INFO_NULL,};




0 0
原创粉丝点击