DC- 20 :二叉树

来源:互联网 发布:qq风险软件 编辑:程序博客网 时间:2024/06/14 04:10
#ifndef __BTREE_H__#define __BTREE_H__#define BLEFT   0#define BRIGHT  1typedef char BTreeData;typedef struct _btreeNode     //节点的类型{BTreeData data;struct _btreeNode *lchild;   struct _btreeNode *rchild;}BTreeNode;typedef struct _btree      // 指向根节点的东西{int count;BTreeNode *root;}BTree;BTree *Create_BTree ();int BTree_Insert (BTree *tree, BTreeData data, int pos, int count, int flag);int Display (BTree *tree);int Delete (BTree *tree, int pos, int count);int BTree_height(BTree *tree);int  BTree_degree (BTree* tree);int BTree_Delete(BTree* tree);int BTree_Clear (BTree* tree);#endif

下面是子函数:

#include "BTree.h"#include <stdlib.h>#include <stdio.h>BTree *Create_BTree (){BTree *btree = (BTree *)malloc(sizeof (BTree) / sizeof (char));if (btree == NULL){return NULL;}btree ->root  = NULL;btree ->count = 0;return btree;}int BTree_Insert (BTree *tree, BTreeData data, int pos, int count, int flag){if (tree == NULL || (flag != BLEFT  && flag != BRIGHT)){return 0;}BTreeNode *node = (BTreeNode*) malloc (sizeof (BTreeNode) / sizeof (char));if (node == NULL){return 0;}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 --;}//flag =way;//挂在以前的节点上if (flag == BLEFT)node ->lchild = current;elsenode ->rchild = current;//把新节点插入二叉树中if (parent != NULL){if (way == BLEFT)parent ->lchild = node;elseparent ->rchild = node;}else{tree ->root  = node;}tree ->count ++;return 0;}r_display (BTreeNode* node, 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);r_display (node ->lchild, gap + 4);r_display (node ->rchild, gap + 4);}int Display (BTree *tree){if (tree == NULL)return 0;r_display (tree ->root,0);}void r_delete (BTree *tree, BTreeNode* node){if (node == NULL || tree == 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 0;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 (parent != NULL){if (way == BLEFT)parent ->lchild = NULL;elseparent ->rchild = NULL;}else{tree ->root  = NULL;}r_delete(tree,current);}//树的高度int r_height (BTreeNode* node){if (node ==NULL){return 0;}int lh =r_height (node ->lchild);int rh =r_height (node ->rchild);return (lh > rh ? lh+1 : rh+1);}int BTree_height(BTree *tree){if (tree == NULL)return 0;int net = r_height(tree ->root);printf ("%d\n",net);return 1;}//求树的度int  r_degree (BTreeNode* node){if (node ==NULL)return 0;int degree = 0;if (node ->lchild != NULL)degree ++;if (node ->rchild != NULL)degree ++;if (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 0;int h = r_degree(tree->root);printf ("%d\n",h);}//删除int BTree_Delete(BTree* tree){if (tree ==NULL)return 0;    Delete (tree, 0, 0);return 0;}//清空int BTree_Clear (BTree* tree){if (tree ==NULL)return 0;BTree_Delete (tree);free (tree);return 0;}

主函数:

#include <stdio.h>#include "BTree.h"int main(){BTree *btree = Create_BTree ();if (btree == NULL)printf ("创建失败\n");else printf ("创建成功\n");BTree_Insert(btree, 'A', 0, 0, 0);BTree_Insert(btree, 'B', 0, 1, 0);BTree_Insert(btree, 'C', 1, 1, 0);BTree_Insert(btree, 'D', 0, 2, 0);BTree_Insert(btree, 'E', 2, 2, 0);BTree_Insert(btree, 'F', 0, 3, 0);BTree_Insert(btree, 'G', 4, 3, 0);BTree_Insert(btree, 'H', 3, 2, 0);//BTree_Insert(btree, 'X', 0, 1, 1);Display (btree);Delete (btree,4,3);    printf ("删除后----------------\n");Display (btree);BTree_degree(btree);printf ("\n");BTree_height(btree);printf ("+---------------------\n");BTree_Clear(btree);Display (btree);printf ("---------------------------\n");BTree_Destroy(&btree);return 0;}
       二叉树的实现没有通用树那么复杂,因为二叉树只有至多两个子节点。这样我们可以轻易定义两个指针分别指向左右两个孩子。

       值得注意的是插入的思路,对于插入的节点,之前位置放置的节点应接在新节点左还是右由flag输入控制,我们认为0左。而如何走到那个点,我们需要一个方法实现,设左走为0,从根节点到第一个子节点为0或1,反向计数,如,深度3的右边为001,我们记为4(100),当出现000,我们只能记为0因此我们还需要一个count来计数。这样我们便完成了步数行走,由此我们可以联想到,用01这种计数方式进行一些选择性行走,可以很简便的转化为二进制运算,这种转化方法用在一些地方可以转化为二叉树模型。记录父节点左右的时候,记录最后一次行走的方向就可以了。

        对于删除与插入思想相类似。打印,高度等便是与通用树相类似的递归。

原创粉丝点击