C语言实现有序二叉树(1)

在cpp中使用的C语言

头文件

 1 /* 有序二叉树 BsTree */
 2 #ifndef _BT_H
 3 #define _BT_H
 4 /*节点*/
 5 typedef struct BsTreeNode
 6 {
 7     int                    data;/* 数据 */
 8     struct BsTreeNode*  left;/* 左子树 */
 9     struct BsTreeNode*  right;/* 右子树 */
10 }BSTREE_NODE;
11 /* 二叉树 */
12 typedef struct BsTree
13 {
14     BSTREE_NODE* root;/* 树根 */
15     size_t       size;/* 大小 */
16 }BSTREE;
17 /* 初始化为空树 */
18 void bstree_init(BSTREE* bstree);
19 /* 释放剩余节点并恢复到初始状态 */
20 void bstree_deinit(BSTREE* bstree);
21 /* 插入 */
22 void bstree_insert(BSTREE* bstree, int data);
23 /* 删除 */
24 bool bstree_erase(BSTREE* bstree, int data);
25 /* 删除所有匹配数据 */
26 void bstree_remove(BSTREE* bstree, int data);
27 /* 清空 */
28 void bstree_clear(BSTREE* bstree);
29 /* 更新 */
30 void bstree_update(BSTREE* bstree, int _old, int _new);
31 /* 判断是否存在 */
32 bool bstree_exist(BSTREE* bstree, int data);
33 /* 中序遍历 */
34 void bstree_travel(BSTREE* bstree);
35 /* 大小 */
36 size_t bstree_size(BSTREE* bstree);
37 /* 高度 */
38 size_t bstree_height(BSTREE* bstree);
39 #endif /*_BT_H*/

实现

  1 /* 有序二叉树 */
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include "bt.h"
  5
  6 /*********************** 内 部 接 口 ********************************/
  7 /* 创建节点 */
  8 static BSTREE_NODE* create_node(int data)
  9 {
 10     BSTREE_NODE* node = (BSTREE_NODE*)malloc(sizeof(BSTREE_NODE));
 11     node->data = data;
 12     node->left = NULL;
 13     node->right = NULL;
 14     return node;
 15 }
 16 /* 销毁节点 */
 17 static void destory_node(BSTREE_NODE* node)
 18 {
 19     free(node);
 20 }
 21 /* 将node节点插入到以root为根的子树中 */
 22 static void insert(BSTREE_NODE* node, BSTREE_NODE** root)
 23 {
 24     if ( NULL == *root )
 25         *root = node;
 26     else if (node)
 27     {
 28         if ( node->data < (*root)->data )
 29             insert(node, &((*root)->left));
 30         else
 31             insert(node, &((*root)->right));
 32     }
 33 }
 34 /* 返回以参数root为根的子树中,数据与参数data匹配的节点的父节点中
 35 *  指向该节点的指针型成员变量的地址
 36 *  目的是在删除节点后,要将删除节点的子节点接到此变量的地址上。
 37 */
 38 static BSTREE_NODE** find(int data, BSTREE_NODE** root)
 39 {
 40     if (NULL == *root)
 41         return root;
 42     if (data < (*root)->data)
 43         return find(data, &(*root)->left);
 44     if (data > (*root)->data)
 45         return find(data, &(*root)->right);
 46     return root;
 47 }
 48 /* 删除以参数root为根的子树 */
 49 static void clear(BSTREE_NODE** root)
 50 {
 51     if (*root)
 52     {
 53         clear(&(*root)->left);
 54         clear(&(*root)->right);
 55         destory_node(*root);
 56         *root = NULL;
 57     }
 58 }
 59 /* 中序遍历以参数root为根的子树 */
 60 static void travel(BSTREE_NODE* root)
 61 {
 62     if (root)
 63     {
 64         travel(root->left);
 65         printf("%d ", root->data);
 66         travel(root->right);
 67     }
 68 }
 69 /* 返回以参数root为根的子树的高度 */
 70 static size_t height(BSTREE_NODE* root)
 71 {
 72     if (root)
 73     {
 74         size_t lh = height(root->left);
 75         size_t rh = height(root->right);
 76         return (((lh > rh) ? lh : rh) + 1);
 77     }
 78     return 0;
 79 }
 80 /*********************** 外 部 接 口 ********************************/
 81 /* 初始化为空树 */
 82 void bstree_init(BSTREE* bstree)
 83 {
 84     bstree->root = NULL;
 85     bstree->size = 0;
 86 }
 87 /* 释放剩余节点并恢复到初始状态 */
 88 void bstree_deinit(BSTREE* bstree)
 89 {
 90     clear(&bstree->root);
 91     bstree->size = 0;
 92 }
 93 /* 插入 */
 94 void bstree_insert(BSTREE* bstree, int data)
 95 {
 96     insert(create_node(data), &bstree->root);
 97     ++bstree->size;
 98 }
 99 /* 删除 */
100 bool bstree_erase(BSTREE* bstree, int data)
101 {
102     BSTREE_NODE** node = find(data, &bstree->root);
103     if (*node)
104     {
105         /* 将匹配节点的左子树插入其右子树 */
106         insert((*node)->left, &(*node)->right);
107         BSTREE_NODE* tmp = *node;
108         /* 用匹配节点的右子树的根节点取代匹配节点 */
109         *node = (*node)->right;
110         /* 销毁匹配节点 */
111         destory_node(tmp);
112         --bstree->size;
113         return true;
114     }
115     return false;
116 }
117 /* 删除所有匹配数据 */
118 void bstree_remove(BSTREE* bstree, int data)
119 {
120     while(bstree_erase(bstree, data));
121 }
122 /* 清空 */
123 void bstree_clear(BSTREE* bstree)
124 {
125     bstree_deinit(bstree);
126 }
127 /* 更新 */
128 void bstree_update(BSTREE* bstree, int _old, int _new)
129 {
130     while(bstree_erase(bstree, _old))
131         bstree_insert(bstree, _new);
132 }
133 /* 判断是否存在 */
134 bool bstree_exist(BSTREE* bstree, int data)
135 {
136     return *find(data, &bstree->root) != NULL;
137 }
138 /* 中序遍历 */
139 void bstree_travel(BSTREE* bstree)
140 {
141     travel(bstree->root);
142     printf("\n");
143 }
144 /* 大小 */
145 size_t bstree_size(BSTREE* bstree)
146 {
147     return bstree->size;
148 }
149 /* 高度 */
150 size_t bstree_height(BSTREE* bstree)
151 {
152     return height(bstree->root);
153 }

测试用例

 1 /* 有序二叉树 */
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 #include "bt.h"
 6
 7 int main ()
 8 {
 9     srand((unsigned)time(NULL));
10     BSTREE bstree;
11     bstree_init(&bstree);
12     int i;
13     for (i = 0; i < 10; ++i)
14         bstree_insert(&bstree, rand()%100);
15
16     bstree_travel(&bstree);
17     bstree_clear(&bstree);
18     bstree_insert(&bstree, 50);
19     bstree_insert(&bstree, 70);
20     bstree_insert(&bstree, 20);
21     bstree_insert(&bstree, 60);
22     bstree_insert(&bstree, 40);
23     bstree_insert(&bstree, 30);
24     bstree_insert(&bstree, 10);
25     bstree_insert(&bstree, 90);
26     bstree_insert(&bstree, 80);
27     bstree_travel(&bstree);
28     printf("大小:%u\n树高:%u\n",
29         bstree_size(&bstree), bstree_height(&bstree));
30
31     bstree_erase(&bstree, 20);
32     bstree_travel(&bstree);
33     bstree_insert(&bstree, 70);
34     bstree_insert(&bstree, 70);
35     bstree_travel(&bstree);
36     bstree_update(&bstree, 70, 200);
37     bstree_travel(&bstree);
38     bstree_remove(&bstree, 200);
39     bstree_travel(&bstree);
40     if (bstree_exist(&bstree, /*20*/40))
41         printf("有!\n");
42     else
43         printf("没有!\n");
44
45     bstree_deinit(&bstree);
46     system("pause");
47     return 0;
48 }

练习:(一般的二叉树)

已知某二叉树前序遍历的结果为:1 2 4 7 3 5 6 8

      中序遍历的结果为:4 7 2 1 5 3 8 6

编写三个函数分别用于重建二叉树、前序遍历和中序遍历。

时间: 2024-10-21 22:48:44

C语言实现有序二叉树(1)的相关文章

二叉查找树(二叉排序树、有序二叉树)算法分析及实现

二叉查找树一般采用二叉链表作为其存储结构,我们这次也采用这样的实现.二叉查找树一般有查找.插入和删除等操作,其中查找是基础,没有查找,插入和删除则无从谈起:而删除算是难点,需处理四种不同的情况,分别是: 无左右孩子,(采取直接删除,须处理其父节点指针) 只有左孩子,(采取其父节点指针指向其左孩子) 只有右孩子.(采取其父节点指针指向其右孩子) 左右孩子都存在,(采取以直接前驱或直接后继代替,实现中我们采用直接前驱代替). 查找的过程比较简单,如果该节点不为空,若其值大于key(要查找的值),则继

c++ 有序二叉树的应用

实作:以有序二叉树记录学生签到时间及名字,然后以名字升序输出学生签到信息 stricmp,strcmpi 原型:extern int stricmp(char *s1,char * s2); 用法:#include <string.h> 功能:比较字符串s1和s2,但不区分字母的大小写. 说明:strcmpi是到stricmp的宏定义,实际未提供此函数. 当s1<s2时,返回值<0 当s1=s2时,返回值=0 当s1>s2时,返回值>0 一.修改 CreateNode

C语言递归实现二叉树的先序、中序、后序遍历

#include <stdio.h> #include <stdlib.h> //*****二叉树的二叉链表存储表示*****// typedef struct BiNode { char data; struct BiNode *lchild, *rchild; }BiNode, *BiTree; //*****按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树构造二叉链表表示的二叉树T*****// void CreateBiTree(BiTree &T) {

数据结构之---C语言实现线索二叉树

//线索二叉树,这里在二叉树的基础上增加了线索化 //杨鑫 #include <stdio.h> #include <stdlib.h> typedef char ElemType; typedef enum {Link,Thread} childTag; //Link表示结点.Thread表示线索 typedef struct bitNode { ElemType data; struct bitNode *lchild, *rchild; int ltag, rtag; } b

C语言树形打印二叉树

学习二叉树时,如果能直观显示,测试程序的时候会方便许多. 实现树形打印的标准方法是利用队列,此处参考的是CSDN上的一篇文章:树状显示二叉树, 原程序使用C++实现,这里使用C. 算法中使用了两个队列,一个用于存储树的结点,另一个用于存储打印过程中每个结点对应的信息. 上一篇文章写了可以利用 void 指针来实现模板,这一次嫌麻烦没有用这个方法,复制粘贴了两个队列. 改天试一试能不能把 void 指针的赋值抽象成一套函数来用用. 如同上面那篇文章中介绍的,此打印程序的核心思想是利用父结点的坐标

c语言编程之二叉树

利用链表建立二叉树,完成前序遍历.中序遍历.后序遍历. 建立二叉树用的是前序遍历建立二叉树: 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<math.h> 4 #include<malloc.h> 5 6 7 typedef int element; 8 typedef struct Tree{ 9 struct Tree *lchild,*rchild; 10 char data; 11 }*pTr

C语言实现最大二叉树并按层遍历

题目:给定一个不含重复元素的整数数组.一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素. 左子树是通过数组中最大值左边部分构造出的最大二叉树. 右子树是通过数组中最大值右边部分构造出的最大二叉树. 通过给定的数组构建最大二叉树,并且输出这个树的根节点. Example 1: 输入: [3,2,1,6,0,5] 输入: 返回下面这棵树的根节点: 6 / 3 5 \ / 2 0 1 分析:(1)通过审题可知通过先序创建二叉树进行创建,即创建根节点,左子树,右子数. 所以选择递归的

C语言递归之二叉树的最大深度

题目描述 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例 给定二叉树 [3,9,20,null,null,15,7] 3 / 9 20 / 15 7 返回它的最大深度 3 . 题目要求 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * struct TreeNode *left; 6 * s

Java版——二叉树

1.一般有2i个节点在第i+1层上,满足这个条件的树称作是完全二叉树. 2.对于所有的非空二叉树,如果它的中间节点都恰好有两个非空子女,那么叶的数目m大于中间节点的数目k,并且m=k+1. 证明:1??如果一个树仅有一个根,那么很容易验证上述条件.假如他对某个树成立,就将两个树连接到一个已存在的树叶上,则该树叶就称为一个中间节点,所以m减少了1,而k增加了1.但是,因为新添加了两个树叶到树上,m有增加了2.增加2且减少1,以及m=k+1,可得等式(m-1)+2=(k+1)+1,正是需要的结果.这