数据结构 - (4)简单二叉树 插入及输出
一、概念
二、完整代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
/*声明结点*/
typedef struct Node {
int val;
struct Node* lchild, * rchild;
}Node;
/*声明树*/
typedef struct Tree {
int* root;
int n;
}Tree;
/*初始化新结点*/
Node* getNewNode(int val) {
Node* node = (Node*)malloc(sizeof(Node));
node->val = val;
node->lchild = node->rchild = NULL;
return node;
}
/*初始化新树*/
Tree *getNewTree() {
Tree* tree = (Tree*)malloc(sizeof(Tree));
tree->n = 0;
tree->root = NULL;
return tree;
}
/*二叉排序树 插值法 (插入成功:ret = 1,否则:ret=0) [递归] */
Node *insertNode(Node *root,int val,int *ret) {
if (root == NULL) {
*ret = 1;
/*初始化一个新结点,将结点插入树*/
return getNewNode(val);
}
/*如果值相等,返回原树*/
if (root->val == val)return root;
/*左小右大*/
if (root->val > val) {
root->lchild = insertNode(root->lchild, val,ret);
}
else {
root->rchild = insertNode(root->rchild, val,ret);
}
/*左小右大插完后,返回树结点(易遗漏)*/
return root;
}
void insert(Tree* tree,int val) {
if (tree == NULL)return;
/*flag判断是否插入成功(0:失败,1:成功)*/
int flag = 0;
/*注意:插入节点后接收返回的树节点*/
tree->root = insertNode(tree->root,val,&flag);//
/*节点数+1*/
tree->n += flag;
return;
}
/*递归输出结点值 【广义表输出】*/
void outputNode(Node *root) {
if (root == NULL)return;
/*先输出根节点的数值*/
printf("%d", root->val);
/*判断并递归到左右子树,输出值*/
if (root->lchild == NULL && root->rchild == NULL)return;
printf("(");
outputNode(root->lchild);
printf(",");
outputNode(root->rchild);
printf(")");
}
/*输出树(调用输出结点)*/
void outputTree(Tree *tree) {
if (tree == NULL)return;
printf("tree(%d):", tree->n);
outputNode(tree->root);
printf("\n");
}
/*清除树结点*/
void clearNode(Node* node) {
if (node == NULL)return;
free(node->lchild);
free(node->rchild);
free(node);
return;
}
/*清除树*/
void clearTree(Tree* tree) {
if (tree == NULL)return;
clearNode(tree->root);
free(tree);
return;
}
/// ////////////////////////////////前序遍历/////////////////////////
/*用了递归,并且要注意Node处判空操作*/
void preorderNode(Node* node) {
if (node == NULL) return;
printf("%d ", node->val);
preorderNode(node->lchild);
preorderNode(node->rchild);
return;
}
void preorder(Tree *tree) {
printf("pre order : ");
preorderNode(tree->root);
printf("\n");
return;
}
////////////////////////////////////中序遍历/////////////////////////
void inorderNode(Node* node) {
if (node == NULL) return;
inorderNode(node->lchild);
printf("%d ", node->val);
inorderNode(node->rchild);
return;
}
void inorder(Tree *tree) {
printf("in order : ");
inorderNode(tree->root);
printf("\n");
return;
}
/// ////////////////////////////////后序遍历/////////////////////////
void postorderNode(Node* node) {
if (node == NULL) return;
postorderNode(node->lchild);
postorderNode(node->rchild);
printf("%d ", node->val);
return;
}
void postorder(Tree *tree) {
printf("post order : ");
postorderNode(tree->root);
printf("\n");
return;
}
int main()
{
srand(time(0));
/*先声明一个树*/
Tree* tree = getNewTree();
for (int i = 0; i < 10; i++) {
int val = rand() % 100;
insert(tree,val);
/*每插入一个值,打印一次*/
outputTree(tree);
}
printf("\n");
preorder(tree);
inorder(tree);
postorder(tree);
clearTree(tree);
return 0;
}
三、分块理解
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
/*声明结点*/
typedef struct Node {
int val;
struct Node* lchild, * rchild;
}Node;
/*声明树*/
typedef struct Tree {
int* root;
int n;
}Tree;
初始化新结点和树(结点包含 值 和 左右子树,数则存放 根节点 及 节点数量)
/*初始化新结点*/
Node* getNewNode(int val) {
Node* node = (Node*)malloc(sizeof(Node));
node->val = val;
node->lchild = node->rchild = NULL;
return node;
}
/*初始化新树*/
Tree *getNewTree() {
Tree* tree = (Tree*)malloc(sizeof(Tree));
tree->n = 0;
tree->root = NULL;
return tree;
}
定义插入二叉树的方法(向二叉树内插入数值,采用 左小右大 的 插入方法 [二叉搜索树])这里需要用到递归,务必认真
/*二叉排序树 插值法 (插入成功:ret = 1,否则:ret=0) [递归] */
Node *insertNode(Node *root,int val,int *ret) {
if (root == NULL) {
*ret = 1;
/*初始化一个新结点,将结点插入树*/
return getNewNode(val);
}
/*如果值相等,返回原树*/
if (root->val == val)return root;
/*左小右大*/
if (root->val > val) {
root->lchild = insertNode(root->lchild, val,ret);
}
else {
root->rchild = insertNode(root->rchild, val,ret);
}
/*左小右大插完后,返回树结点(易遗漏)*/
return root;
}
void insert(Tree* tree,int val) {
if (tree == NULL)return;
/*flag判断是否插入成功(0:失败,1:成功)*/
int flag = 0;
/*注意:插入节点后接收返回的树节点*/
tree->root = insertNode(tree->root,val,&flag);//
/*节点数+1*/
tree->n += flag;
return;
}
通过递归将树打印出,同样需要细心
/*递归输出结点值 【广义表输出】*/
void outputNode(Node *root) {
if (root == NULL)return;
/*先输出根节点的数值*/
printf("%d", root->val);
/*判断并递归到左右子树,输出值*/
if (root->lchild == NULL && root->rchild == NULL)return;
printf("(");
outputNode(root->lchild);
printf(",");
outputNode(root->rchild);
printf(")");
}
/*输出树(调用输出结点)*/
void outputTree(Tree *tree) {
if (tree == NULL)return;
printf("tree(%d):", tree->n);
outputNode(tree->root);
printf("\n");
}
定义清除树的方法
/*清除树结点*/
void clearNode(Node* node) {
if (node == NULL)return;
free(node->lchild);
free(node->rchild);
free(node);
return;
}
/*清除树*/
void clearTree(Tree* tree) {
if (tree == NULL)return;
clearNode(tree->root);
free(tree);
return;
}
前、中、后序遍历
/// ////////////////////////////////前序遍历/////////////////////////
/*用了递归,并且要注意Node处判空操作*/
void preorderNode(Node* node) {
if (node == NULL) return;
printf("%d ", node->val);
preorderNode(node->lchild);
preorderNode(node->rchild);
return;
}
void preorder(Tree *tree) {
printf("pre order : ");
preorderNode(tree->root);
printf("\n");
return;
}
////////////////////////////////////中序遍历/////////////////////////
void inorderNode(Node* node) {
if (node == NULL) return;
inorderNode(node->lchild);
printf("%d ", node->val);
inorderNode(node->rchild);
return;
}
void inorder(Tree *tree) {
printf("in order : ");
inorderNode(tree->root);
printf("\n");
return;
}
/// ////////////////////////////////后序遍历/////////////////////////
void postorderNode(Node* node) {
if (node == NULL) return;
postorderNode(node->lchild);
postorderNode(node->rchild);
printf("%d ", node->val);
return;
}
void postorder(Tree *tree) {
printf("post order : ");
postorderNode(tree->root);
printf("\n");
return;
}
主函数:随机对树进行10次插值操作,再调用前中后序遍历,清空二叉树
int main()
{
srand(time(0));
/*先声明一个树*/
Tree* tree = getNewTree();
for (int i = 0; i < 10; i++) {
int val = rand() % 100;
insert(tree,val);
/*每插入一个值,打印一次*/
outputTree(tree);
}
printf("\n");
preorder(tree);
inorder(tree);
postorder(tree);
clearTree(tree);
return 0;
}
本文作者:HanaKoo
本文链接:https://www.cnblogs.com/HanaKoo/p/16143955.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步