|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 mingcxx 于 2016-9-6 01:05 编辑
这份二叉搜索树的接口有几个重要的函数是用递归实现的,譬如AddNode(), InOrder()等等,所以内存开销应该比其他算法要大了些。(算法接下来才学 )
- /*tree.h -- 二叉搜索树的接口头文件*/
- /*树中不允许有相同的项目*/
- #ifndef _TREE_H_
- #define _TREE_H_
- #include <stdbool.h>
- /*您可以在这里把Item定义为适合的类型*/
- typedef struct item
- {
- char petname[20];
- char petkind[20];
- } Item;
- #define MAXITEMS 10
- typedef struct node
- {
- Item item;
- struct node * left; /*指向左分支的指针*/
- struct node * right; /*指向右分支的指针*/
- } Node;
- typedef struct tree
- {
- Node * root; /*指向树根的指针*/
- int size; /*树中项目的个数*/
- } Tree;
- /*函数原型*/
- /*操作: 把一个树初始化为一个空树*/
- /*操作前:ptree指向一个树*/
- /*操作后:该树已被初始化为空树*/
- void InitializeTree(Tree * ptree);
- /*操作: 确定树是否为空*/
- /*操作前:ptree指向一个树*/
- /*操作后:如果树为空则函数返回tree,
- 否则返回false*/
- bool TreeIsEmpty(const Tree * ptree);
- /*操作: 确定树是否已满*/
- /*操作前:ptree指向一个树*/
- /*操作后:如果树已满则函数返回tree,
- 否则返回false*/
- bool TreeIsFull(const Tree * ptree);
- /*操作: 确定树中项目的个数*/
- /*操作前:ptree指向一个树*/
- /*操作后:函数返回树中项目的个数*/
- int TreeItemCount(const Tree * ptree);
- /*操作: 向树中添加一个项目*/
- /*操作前:pi是待添加项目的地址
- ptree指向一个已初始化的树*/
- /*操作后:如果可能,函数把项目添加到树中
- 并返回tree,否则返回false*/
- bool AddItem(const Item * pi, Tree * ptree);
- /*操作: 在树中查找一个项目*/
- /*操作前:pi指向一个项目,
- ptree指向一个已初始化的树*/
- /*操作后:如果项目在树中,则函数返回tree,
- 否则返回false*/
- bool InTree(const Item * pi, const Tree * ptree);
- /*操作: 从树中删除一个项目*/
- /*操作前:pi是待删除项目的地址
- ptree指向一个已初始化的树*/
- /*操作后:如果可能,函数从树中删除该项目
- 并返回tree,否则返回false*/
- bool DeleteItem(const Item * pi, Tree * ptree);
- /*操作: 把一个函数作用于树中每一个项目*/
- /*操作前:ptree指向一棵树,
- pfun指向一个没有返回值的函数,
- 该函数接受一个Item作为参数*/
- /*操作后:pfun指向的函数被作用于树中
- 每一个项目一次*/
- void Traverse(const Tree * ptree, void(*pfun)(Item item));
- /*操作: 从树中删除所有节点*/
- /*操作前:ptree指向一个已初始化的树*/
- /*操作后:该树为空树*/
- void EmptyAll(Tree * ptree);
- #endif // !_TREE_H_
复制代码- //tree.c -- 二叉搜索树类型的实现接口
- #include <stdio.h>
- #include <stdlib.h> //malloc(), free()
- #include <stdbool.h>
- #include <string.h> //strcmp()
- #include "tree.h"
- //局部数据类型
- typedef struct pair
- {
- Node * parent;
- Node * child;
- } Pair;
- //局部函数原型
- static Node * MakeNode(const Item * pi);
- static bool ToLeft(const Item * pi1, const Item * pi2);
- static bool ToRight(const Item * pi1, const Item * pi2);
- static void AddNode(Node * pnew_node, Node * root);
- static void InOrder(const Node * root, void(*pfun)(Item item));
- static Pair SeekItem(const Item * pi, const Tree * ptree);
- static void DeleteNode(Node ** ptr);
- static void DeleteAllNodes(Node * root);
- //函数定义
- void InitializeTree(Tree * ptree)
- {
- ptree->root = NULL;
- ptree->size = 0;
- }
- bool TreeIsEmpty(const Tree * ptree)
- {
- if (ptree->root == NULL)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- bool TreeIsFull(const Tree * ptree)
- {
- if (ptree->size == MAXITEMS)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- int TreeItemCount(const Tree * ptree)
- {
- return ptree->size;
- }
- bool AddItem(const Item * pi, Tree * ptree)
- {
- Node * pnew_node;
- //检查树是否已满
- if (TreeIsFull(ptree))
- {
- fprintf(stderr, "Tree is full.\n");
- return false;
- }
- //检查欲添加项是否已存在
- if (SeekItem(pi, ptree).child != NULL)
- {
- fprintf(stderr, "Attempted to add duplicate item.\n");
- return false;
- }
- //尝试创建新节点
- pnew_node = MakeNode(pi);
- if (pnew_node == NULL)
- {
- fprintf(stderr, "Couldn't create node.\n");
- return false;
- }
- //创建成功,更新树结构
- ptree->size++;
- if (ptree->root == NULL)
- {
- ptree->root = pnew_node;
- }
- else
- {
- AddNode(pnew_node, ptree->root);
- }
- return true;
- }
- bool InTree(const Item * pi, const Tree * ptree)
- {
- return SeekItem(pi, ptree).child == NULL ? false : true;
- }
- bool DeleteItem(const Item * pi, Tree * ptree)
- {
- Pair look;
- look = SeekItem(pi, ptree);
- if (look.child == NULL)
- {
- return false; //失败返回
- }
- if (look.parent == NULL)
- {
- DeleteNode(&ptree->root);
- }
- else if (look.parent->left == look.child)
- {
- DeleteNode(&look.parent->left);
- }
- else
- {
- DeleteNode(&look.parent->right);
- }
- ptree->size--;
- return true;
- }
- void Traverse(const Tree * ptree, void(*pfun)(Item item))
- {
- if (ptree->root != NULL)
- {
- InOrder(ptree->root, pfun);
- }
- }
- void EmptyAll(Tree * ptree)
- {
- if (ptree->root != NULL)
- {
- DeleteAllNodes(ptree->root);
- }
- ptree->root = NULL;
- ptree->size = 0;
- }
- //局部函数定义
- Node * MakeNode(const Item * pi)
- {
- Node * pnew_node;
- pnew_node = (Node *)malloc(sizeof(Node)); //分配节点内存
- if (pnew_node != NULL) //分配到时进行节点的初始化
- {
- pnew_node->item = *pi;
- pnew_node->left = NULL;
- pnew_node->right = NULL;
- }
- return pnew_node;
- }
- bool ToLeft(const Item * pi1, const Item * pi2)
- {
- int comp1;
- if ((comp1 = strcmp(pi1->petname, pi2->petname)) < 0)
- {
- return true;
- }
- else if (comp1 == 0 && strcmp(pi1->petkind, pi2->petkind) < 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- bool ToRight(const Item * pi1, const Item * pi2)
- {
- int comp1;
- if ((comp1 = strcmp(pi1->petname, pi2->petname)) > 0)
- {
- return true;
- }
- else if (comp1 = 0 && strcmp(pi1->petkind, pi2->petkind) > 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- void AddNode(Node * pnew_node, Node * root) //递归
- {
- if (ToLeft(&pnew_node->item, &root->item))
- {
- if (root->left == NULL)
- {
- root->left = pnew_node;
- }
- else
- {
- AddNode(pnew_node, root->left);
- }
- }
- else if (ToRight(&pnew_node->item,&root->item))
- {
- if (root->right == NULL)
- {
- root->right = pnew_node;
- }
- else
- {
- AddNode(pnew_node, root->right);
- }
- }
- else
- {
- fprintf(stderr, "location error in AddNode().\n");
- exit(EXIT_FAILURE);
- }
- }
- void InOrder(const Node * root, void(*pfun)(Item item)) //递归
- {
- //递归调用访问非空的子树,遍历顺序:中序遍历
- if (root != NULL)
- {
- InOrder(root->left, pfun);
- (*pfun)(root->item);
- InOrder(root->right, pfun);
- }
- }
- Pair SeekItem(const Item * pi, const Tree * ptree) //递归
- {
- Pair look;
- look.parent = NULL;
- look.child = ptree->root;
- if (look.child == NULL)
- {
- return look; //空树返回
- }
- while (look.child != NULL)
- {
- if (ToLeft(pi, &look.child->item))
- {
- look.parent = look.child;
- look.child = look.child->left;
- }
- else if (ToRight(pi, &look.child->item))
- {
- look.parent = look.child;
- look.child = look.child->right;
- }
- else
- {
- break; //如果前两种情况都不满足,必定为相等的情况,中断循环,look.child等于目标节点的地址
- }
- }
- return look;
- }
- void DeleteNode(Node ** ptr)
- {
- Node * temp;
- puts((*ptr)->item.petname);
- if ((*ptr)->left == NULL)
- {
- *ptr = (*ptr)->right; //只有右支时,让待删节点的父节点中指向该节点的指针,修改为指向待删节点的右子树
- }
- else if ((*ptr)->right == NULL)
- {
- *ptr = (*ptr)->left; //同上
- }
- else //待删节点有2个子节点
- {
- //在左子树的右支查找空的右子树
- for (temp = (*ptr)->left; temp->right == NULL; temp = temp->right)
- {
- continue;
- }
- temp->right = (*ptr)->right;
- temp = *ptr;
- *ptr = temp->left;
- free(temp);
- }
- }
- void DeleteAllNodes(Node * root) //递归
- {
- Node *pright;
- if (root != NULL)
- {
- //中序遍历删除非空的子树
- pright = root->right;
- DeleteAllNodes(root->left);
- free(root);
- DeleteAllNodes(pright);
- }
- }
复制代码 |
|