数据结构之二叉树

来源:互联网 发布:mysql 字段值加一 编辑:程序博客网 时间:2024/06/06 03:40

二叉树的每个结点至多只有两个孩子节点(不存在度大于2的结点),二叉树的孩子节点有左右之分,次序不能颠倒。

头文件:

btree.h

#ifndef __BTREE_H__#define __BTREE_H__#include "error.h"#define BLEFT 0   //表示插入二叉树的左边#define BRIGHT 1   //表示插入二叉树的右边typedef char BTreeData;   //事先声明//二叉树的节点typedef struct _btreeNode{BTreeData data;struct _btreeNode *lchild;  //指向左孩子节点的指针struct _btreeNode *rchild;  //指向右孩子节点的指针}BTreeNode;//二叉树typedef struct _btree{BTreeNode *root;            //指向二叉树的根节点int count;                 //记录二叉树节点的个数}BTree;typedef void (*Print_BTree)(BTreeNode*);// 创建一棵二叉树BTree *Create_BTree();// pos 走的路径 值类似 110(左右右)  011 (右右左)// count  代表走的步数// flag   代表被替换的结点应该插入在新节点的位置,如果是BLEFT 表示插在左边,BRIGHT表示插在右边int Btree_Insert(BTree *tree, BTreeData data, int pos, int count, int flag);//打印树void Display (BTree* tree, Print_BTree pfunc);//删除节点int Delete (BTree *tree, int pos, int count);//求树的高度int BTree_Height (BTree *);//求树的度int BTree_Degree (BTree *);//清空树int BTree_Clear (BTree *);//销毁树int BTree_Destroy (BTree **);// 前序遍历void pre_order (BTreeNode *node);//中序遍历void mid_order (BTreeNode *node);//后序遍历void last_order (BTreeNode *node);#endif // __BTREE_H__


源文件:

btree.c

#include "btree.h"#include <stdlib.h>#include <stdio.h>// 创建一棵二叉树BTree *Create_BTree(){BTree *btree = (BTree*)malloc(sizeof(BTree)/sizeof(char));if (btree == NULL){errno = MALLOC_ERROR;return NULL;}btree->count = 0;   //树节点个数为0btree->root = NULL;   //根节点指针为空,树为空return btree;}// pos 走的路径 值类似 110(左右右)  011 (右右左)// count  代表走的步数// flag   代表被替换的结点应该插入在新节点的位置,如果是BLEFT 表示插在左边,BRIGHT表示插在右边int Btree_Insert(BTree *tree, BTreeData data, int pos, int count, int flag){if (tree == NULL || (flag != BLEFT && flag != BRIGHT)){return FALSE;}BTreeNode *node = (BTreeNode*)malloc(sizeof(BTreeNode)/sizeof(char));if (node == NULL){errno = MALLOC_ERROR;return FALSE;}//初始化节点node->data = data;node->lchild = NULL;node->rchild = NULL;//找插入的位置BTreeNode *parent = NULL;BTreeNode *current = tree->root;  //current一开始指向根节点,根节点的父节点是空int way;  //保存当前走的位置while (count > 0 && current != NULL){way = pos & 1;   //取出当前走的方向pos = pos >> 1;  //移去走过的路线//当前位置就是走完以后的位置的父节点parent = current;if (way == BLEFT)  //往左走{current = current->lchild;}else               //往右走{current = current->rchild;}count--;}//把被替换掉的节点插入到新节点下面if (flag == BLEFT){node->lchild = current;}else{node->rchild = current;}//把新节点插入到二叉树中,way保存了应该插入在父节点的左边还是右边if (parent != NULL){if(way == BLEFT){parent->lchild = node;}else{parent->rchild = node;}}else{tree->root = node;  //替换根节点}tree->count++;return TRUE;}//递归打印void r_display(BTreeNode* node,Print_BTree pfunc,int gap){int i;if (node == NULL)       //打印空孩子前的“-”{for(i = 0;i < gap;i++){printf ("-");}printf ("\n");return;}for (i = 0;i < gap;i++){printf ("-");}//打印节点//printf ("%c\n",node->data);pfunc (node);//若是左右孩子都为空,就不打印if (node->lchild != NULL || node->rchild != NULL){//打印左孩子r_display (node->lchild,pfunc,gap+4);//打印右孩子r_display (node->rchild,pfunc,gap+4);}}//打印树void Display (BTree* tree, Print_BTree pfunc){if (tree == NULL){return;}r_display(tree->root,pfunc,0);}//递归删除void r_delete (BTree *tree,BTreeNode *node){if (tree == NULL || node == NULL){return;}//先删除左孩子r_delete (tree,node->lchild);//删除右孩子r_delete (tree,node->rchild);free(node);   //释放掉节点tree->count--;}//删除节点int Delete (BTree *tree, int pos, int count){if (tree == NULL){return FALSE;}//找节点BTreeNode* parent = NULL;BTreeNode* current = tree->root;int way;while (count > 0 && current != NULL){way = pos & 1;pos = pos >> 1;parent = current;if (way == BLEFT){current = current->lchild;}else{current = current->rchild;}count--;}//将该节点从树上移除if (parent != NULL){if (way == BLEFT){parent->lchild = NULL;}else{parent->rchild = NULL;}}else{tree->root = NULL;  //移除根节点}//释放节点r_delete (tree,current);return TRUE;}//递归求树的高度int r_height (BTreeNode* node){if (node == NULL){return FALSE;}//求左孩子的高度int lh = r_height (node->lchild);//求右孩子的高度int rh = r_height (node->rchild);//节点的高度是孩子中最高的高度+1return (lh > rh ? lh+1 : rh+1);}//求树的高度int BTree_Height (BTree *tree){if (tree == NULL){return FALSE;}int ret = r_height(tree->root);return ret;}//递归求树的度int r_degree (BTreeNode *node){if (node == NULL){return 0;}int degree = 0;if (node->lchild != NULL){degree++;}if (node->rchild != NULL){degree++;}//度为0代表没有左右孩子,度为2,代表树的度为2if (degree == 1){int ld = r_degree (node->lchild);if (ld == 2){return 2;}int rd = r_degree (node->rchild);if (rd == 2){return 2;}}return degree;}//求树的度int BTree_Degree (BTree *tree){if (tree == NULL){return FALSE;}int ret = r_degree(tree->root);return ret;}//清空树int BTree_Clear (BTree *tree){if(tree == NULL){return FALSE;}Delete (tree,0,0);  //删除根节点tree->root = NULL;return TRUE;}//销毁树int BTree_Destroy (BTree **tree)  //二级指针{if (tree == NULL){return FALSE;}BTree_Clear (*tree);free (*tree);*tree = NULL;return TRUE;}// 前序遍历void pre_order (BTreeNode *node){if (node == NULL){return;}printf ("%4c", node->data);  //最先打印根节点pre_order (node->lchild);pre_order (node->rchild);}//中序遍历void mid_order (BTreeNode *node){if (node == NULL){return;}mid_order (node->lchild);printf ("%4c", node->data);    //中间打印根节点mid_order (node->rchild);}//后序遍历void last_order (BTreeNode *node){if (node == NULL){return;}last_order (node->lchild);last_order (node->rchild);printf ("%4c", node->data);     //最后打印根节点}




关于二叉树的更多的操作,比如非递归实现二叉树遍历,可以大家一起去实现。

原创粉丝点击