2022-04-14 12:00阅读: 490评论: 0推荐: 0

数据结构 - (4)简单二叉树 插入及输出

一、概念

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点  
 

二、完整代码

#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 中国大陆许可协议进行许可。

posted @   HanaKoo  阅读(490)  评论(0编辑  收藏  举报
@format
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 Tiny Light(TV动画《地缚少年花子君》ED)(翻自 鬼頭明里) 柚卟
Tiny Light(TV动画《地缚少年花子君》ED)(翻自 鬼頭明里) - 柚卟
00:00 / 00:00
An audio error has occurred.

作词 : Saku

作曲 : Saku

優しさに触れて残る温度

消えないまま 愛しいと言えたら

心は軽くなるかな

閉ざした扉の向こうで

微かな声が聴こえてる

踏み出すことさえも出来ないから

孤独に寄り添ってる

まだこの胸の中 生きづいたまま

小さな灯し火のような想いを

風に吹かれぬように

雨に濡れないように

ずっと抱きしめてた

ただ 真っ直ぐなまま願う強さも

泣き出しそうになる脆い自分も

君が居なきゃ知らなかったんだよ

偶然の中で運命を見つけた

瞳閉じる度 記憶の海 漂っては

深い夢のあと

面影を探してたんだ

変わらないモノクロの日々に

君が色を添えてくから

滲んだ過去さえもいつの間にか

意味を持ち始めてる

まだこの胸の中隠したままの

痛いほど愛おしい こんな思いを

いつか消えてしまうその前に

届けたい人は 君だけなんだ

どんな涙も どんな笑顔も

全ては君のためにあるから

まだこの胸の中 生きづいたまま

小さな灯し火のような想いを

風に吹かれぬように

雨に濡れないように

ずっと抱きしめてた

ただ 真っ直ぐなまま願う強さも

泣き出しそうになる脆い自分も

君が居なきゃ知らなかったんだよ

偶然の中で運命を見つけた

君がいるだけで世界は変わった