二叉树的创建和相关算法

二叉树是一种非常重要的数据结构,它是分支结构的基础,今天本人将写一篇博客来叙述一下其相关的算法以及二叉树的创建过程!

1:二叉树的创建:

主要有 先序,中序,后序,层序创建几种方式,其中前三种建立在二叉树遍历方式的基础上的。

(1):先序创建

先序创建就是先创建根节点,随后依次创建其左子树和右子树,我们可以采用递归的方法来实现,因为二叉树本身就是建立在递归算法的基础上的。

(2):中序和后序创建:

明白了前序创建二叉树的方式,中序和后续我们也可以类比出来,所谓前中后序,就是创建根节点的顺序而已。

(3):层序遍历和创建:

以上图片反映的层序遍历的过程,层序遍历是建立在队列的基础上的,首先如果一颗二叉树非空,让根节点入队,如果根节点的左子树后右子树非空,则根节点出队并打印它的数据域的值,左右子树先后入队(谁不空谁入队),随后就是一个递归的过程了。

可见层序遍历是从上到下,从左到右的一个遍历过程。

所以我们也可以层序创建一个二叉树:首先创建根节点,如果根节点的左孩子和右孩子指针没有指向虚结点,则创建左子树和右子树,也是通过递归的方式来创建的。

二叉树代码:

函数文件 Bittree.c:

#include "Bittree.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

tree *Creat(tree* root, tree*(*ptree)(tree *root))
{
	root = ptree(root);
	return root;
}
tree *Tier_creat(tree* root)   //层序创建二叉树    root为根节点
{

	tree *s = NULL;
	datatype data = 0;
	tree *Tree_arr[MAX] = { 0 };       //创建一个存储二叉树结点的队列
	int front = 1;                     //front为队列指针初值
	int rear = 0;                      //rear为队列末尾指针初值
	printf("层数创建二叉树,以-1表示虚结点,-2表示结束!\n");
	scanf("%d", &data);
	while (data != -2)
	{
		s = NULL;
		if (data != -1)
		{
			s =(tree*) malloc(sizeof(tree)* 1);
			s->data = data;
			s->Lchild = NULL;
			s->Rchild = NULL;
	    }
		rear++;
		Tree_arr[rear] = s;           //双亲节点入队
		if (rear == 1) root = s;      //如果rear为队头指针,则其队列中存储的为二叉树的根节点
		else
		{
			if (Tree_arr[rear] && s)     //孩子和双亲都不是虚结点
			{
				if (rear % 2 == 0)   Tree_arr[front]->Lchild = s;        //新节点是左孩子
				if (rear % 2 == 1)
				{
					Tree_arr[front]->Rchild = s;    //新节点是右孩子
					front++;                        //如果是此时rear指向右孩子,则出队,下一个节点进队
				}
			}
		}
		scanf("%d", &data);
    }
	return root;
}
tree *DLR_creat(tree* root)    //先序创建二叉树
{
	printf("以-1表示指针域为空,以-2表示结束创建过程\n");
	root = NULL;
	int data = 0;
	printf("请输入数据:");
	scanf("%d", &data);
    if (data == -1)
		return NULL;
    root = (tree*)malloc(sizeof(tree)* 1);
	if (root == NULL)
		 {
			printf("创建失败!\n");
			exit(EXIT_FAILURE);
		 }
	 root->data = data;
	 root->Lchild=DLR_creat(root->Lchild);
     root->Rchild = DLR_creat(root->Rchild);
     return root;
}
tree *LDR_creat(tree* root)    //中序创建二叉树
{
	printf("以-1表示指针域为空,以-2表示结束创建过程\n");
	root = NULL;
	int data = 0;
	printf("请输入数据:");
	scanf("%d", &data);
	if (data == -1)
		return NULL;
	root->Lchild = DLR_creat(root->Lchild);
	root = (tree*)malloc(sizeof(tree)* 1);
	if (root == NULL)
	{
		printf("创建失败!\n");
		exit(EXIT_FAILURE);
	}
	root->data = data;
	root->Rchild = DLR_creat(root->Rchild);
	return root;
}
tree *RLD_creat(tree* root)    //后序创建二叉树
{
	printf("以-1表示指针域为空,以-2表示结束创建过程\n");
	root = NULL;
	int data = 0;
	printf("请输入数据:");
	scanf("%d", &data);
	if (data == -1)
		return NULL;
    root->Lchild = DLR_creat(root->Lchild);
	root->Rchild = DLR_creat(root->Rchild);
	root = (tree*)malloc(sizeof(tree)* 1);
	if (root == NULL)
	{
		printf("创建失败!\n");
		exit(EXIT_FAILURE);
	}
	root->data = data;
	return root;
}
void Print_Tree(tree *root, void(*ptree)(tree *root))  //遍历二叉树
{
	assert(root);
	if (root == NULL)
	{
		printf("树是空树!\n");
		return;
	}
	else
	{
		ptree(root);
		printf("\n");
	}
}
void DLR_Print(tree *root)      //先序遍历二叉树
{

	if (root != NULL)
	{
		printf("%d  ", root->data);
	    DLR_Print(root->Lchild);
	    DLR_Print(root->Rchild);
	}
	return;

}
void LDR_Print(tree *root)      //中序遍历二叉树
{

	if (root != NULL)
	{
		DLR_Print(root->Lchild);
		printf("%d  ", root->data);
		DLR_Print(root->Rchild);
	}
	return;
}
void RLD_Print(tree *root)      //后序遍历二 叉树
{

	if (root != NULL)
	{
		DLR_Print(root->Lchild);
		DLR_Print(root->Rchild);
		printf("%d  ", root->data);
	}
	return;
}
void Tie_Print(tree *root)             //层序遍历二叉树
{
	tree* arry[MAX] = { 0 };
	int rear = 1;
	int front = 0;
	if (root == NULL)
	{
		printf("二叉树为空!\n");
		return;
	}
	else
	{
		arry[0] = root;                    //如果二叉树不为空,根节点先入队。
		while (front < rear)               //循环条件   队列非空
		{
			if (arry[front])
			{
				printf("%d ", arry[front]->data);
				arry[rear++] = arry[front]->Lchild;
				arry[rear++] = arry[front]->Rchild;
				front++;
			}
			else
			{
				front++;
			}
		}
	}
}

int Deep_tree(tree *root)     //求二叉树的深度
{
	assert(root);
	int left = 0;
	int right = 0;
	int deep = 0;
	if (root != NULL)
	{
		left=Deep_tree(root->Lchild);             //求左子树深度
		right = Deep_tree(root->Rchild);          //求右子树深度
		deep = left > right ? (left + 1) : (right + 1);
	}
	return deep;
}
int Node_du(tree *root)      //求某个节点的度
{
	assert(root);
	int ret = 0;
	if (root == NULL)
		return 0;
	else
	{
		if (root->Lchild != NULL)
			ret++;
		if (root->Rchild != NULL)
			ret++;
		return ret;
	}
}

int tree_Node(tree *root)
{
	assert(root);
	int ret = 0;
	if (root == NULL)
		return 0;
	if (root->Lchild == NULL&&root->Rchild == NULL)        //叶子节点
		return 1;
	ret =1+ tree_Node(root->Lchild) + tree_Node(root->Rchild);
	return ret;
}

tree* search_Node(tree *root, datatype data)                //查找值为data的节点
{
	assert(root);
	tree *p=NULL;
	if (root == NULL)
	{
		printf("树是空树!\n");
		return NULL;
	}
	else
	{
		if (root->data == data)
			return root;
		if (root->Lchild != NULL)
		{
			p = search_Node(root->Lchild,data);
			if (p != NULL)
				return p;
		}

		if (root->Rchild != NULL)
		{
			p = search_Node(root->Rchild,data);
			if (p != NULL)
				return p;
		}
		return NULL;   //没找到返回空
	}
}

void Deal_tree(tree *root)   //释放内存
{
	assert(root);
	if (root == NULL)
		return;
	Deal_tree(root->Lchild);
	Deal_tree(root->Rchild);
	free(root);
	root = NULL;
}

头文件  Bittree.h

#ifndef __BITTREE_H__
#define __BITTREE_H__
#define _CRT_SECURE_NO_WARNINGS
#define MAX  100
typedef int datatype;
typedef struct Bittree
{
	datatype data;
	struct Bittree *Lchild;
	struct Bittree *Rchild;

}tree;
typedef struct
{
	datatype Elem_data[MAX];
	int length;
}Tree_arry;
tree *Tier_creat(tree* root);   //层序创建二叉树    root为根节点
tree *DLR_creat(tree* root);    //先序创建二叉树
tree *LDR_creat(tree* root);    //中序创建二叉树
tree *RLD_creat(tree* root);    //后序创建二叉树
tree *Creat(tree* root,tree*(*ptree)(tree *root));     //创建二叉树
void Print_Tree(tree *root, void(*ptree)(tree *root));  //遍历二叉树
void DLR_Print(tree *root);      //先序遍历二叉树
void LDR_Print(tree *root);      //中序遍历二叉树
void RLD_Print(tree *root);      //后序遍历二叉树
void Tie_Print(tree *root);      //层序遍历二叉树
int Deep_tree(tree *root);       //求二叉树的深度
int Node_du(tree *root);          //求某个节点的度
int tree_Node(tree *root);       //求树的节点的个数
tree* search_Node(tree *root, datatype data);                //查找值为data的节点
void Deal_tree(tree *root);       //释放内存

#endif __BITTREE_H__

测试文件test.c:

#include "Bittree.h"
#include <stdio.h>
#include <stdlib.h>
void Init()
{
	printf("1:二叉树的创建\n");
	printf("2:二叉树的遍历\n");
	printf("3:二叉树的深度查询\n");
	printf("4:二叉树的某一个节点的度的查询\n");
	printf("5:清空二叉树\n");
	printf("0:退出\n");
}
void Init_Print()
{
	printf("0:层序遍历二叉树.\n");
	printf("1:先序遍历二叉树.\n");
	printf("2:后序遍历二叉树.\n");
	printf("3:中序遍历二叉树.\n");
}
void Init_Creat()
{
	printf("0:层序创建二叉树.\n");
	printf("1:先序创建二叉树.\n");
	printf("2:后序创建二叉树.\n");
	printf("3:中序创建二叉树.\n");
}
void  test()
{
	int ret;
	int key=0;
	int choose;
	datatype data=0;
	tree *root = NULL;
	tree *node = NULL;
	tree* (*Tree_C[4])(tree *root) = { 0 };   //函数指针数组存放二叉树的创建方式
	void(*Tree_p[4])(tree *root) = { 0 };   //函数指针数组存放二叉树的遍历方式
	Tree_C[0] = Tier_creat;
	Tree_C[1] = DLR_creat;
	Tree_C[2] = LDR_creat;
	Tree_C[3] = RLD_creat;
	Tree_p[0] = Tie_Print;
	Tree_p[1] = DLR_Print;
	Tree_p[2] = LDR_Print;
	Tree_p[3] = DLR_Print;
	while (1)
	{
		printf("请输入你的选择:");
		scanf("%d", &key);
		switch (key)
		{
		case 0:
			printf("Program Over!!\n");
			exit(EXIT_FAILURE);
			break;
		case 1:
			Init_Creat();
			do
			{
				printf("请输入你的选择:");
				scanf("%d", &choose);
			} while (choose <= 0 && choose >= 3);
			root = Creat(root, Tree_C[choose]);
			break;
		case 2:
			Init_Print();
			do
			{
				printf("请输入你的选择:");
				scanf("%d", &choose);
			} while (choose <= 0 && choose >= 3);
			Print_Tree(root, Tree_p[choose]);
			break;
		case 3:
			ret = Deep_tree(root);
			printf("二叉树的深度为:%d\n", ret);
			break;
		case 4:
			printf("请输入你要查询节点所保存的数据:");
			scanf("%d", &data);
			node=search_Node(root, data);
			if (node == NULL)
			{
				printf("你所要查询的节点不存在!\n");
				exit(EXIT_FAILURE);
			}
			ret = Node_du(node);
			printf("数据为%d的节点的度为:%d\n",data, ret);
			break;
		case 5:
			Deal_tree(root);
			printf("清空成功!\n");
			break;
		}
	}
}

int main()
{
	Init();
	test();
	system("pause");
	return 0;
}

如果上述叙述有相关问题请大家能指出,本人邮箱:[email protected]

时间: 2024-11-29 07:34:36

二叉树的创建和相关算法的相关文章

数据结构与算法第10周作业——二叉树的创建和遍历算法

一.二叉树的创建算法(递归方式) 二.二叉树的先序.中序和后序遍历算法 #include<stdio.h>#include<stdlib.h>typedef struct TNode{ struct TNode *lchild; int data; struct TNode *rchild;}TNode,*BTree;void createBiTree(BTree &T){ char x; scanf("%d",&x); if(x!=0) { T

数据结构-第10周作业(二叉树的创建和遍历算法)

数据结构与算法 3:二叉树,遍历,创建,释放,拷贝,求高度,面试,线索树

[本文谢绝转载,原文来自http://990487026.blog.51cto.com] 树 数据结构与算法 3:二叉树,遍历,创建,释放,拷贝,求高度,面试,线索树 二叉树的创建,关系建立 二叉树的创建,关系建立2 三叉链表法 双亲链表: 二叉树的遍历 遍历的分析PPT 计算二叉树中叶子节点的数目:使用全局变量计数器 计算二叉树中叶子节点的数目:不使用全局变量计数器 无论是先序遍历,中序遍历,后序遍历,求叶子的数字都不变;因为本质都是一样的,任何一个节点都会遍历3趟 求二叉树的高度 二叉树的拷

算法实验-二叉树的创建和前序-中序-后序-层次 遍历

对于二叉树的创建我是利用先序遍历的序列进行创建 能够对于树节点的内容我定义为char型变量 '0'为空,即此处的节点不存在 头文件 Tree.h //链式二叉树的头文件 #pragma once #include<iostream> #include<queue> using namespace std; class BinaryTreeNode { public: char data; BinaryTreeNode *leftChild,*rightChild; BinaryTr

Java创建树形结构算法实例

在JavaWeb的相关开发中经常会涉及到多级菜单的展示,为了方便菜单的管理需要使用数据库进行支持,本例采用相关算法讲数据库中的条形记录进行相关组装和排序讲菜单组装成树形结构. 首先是需要的JavaBean 1 2 3 import java.io.Serializable; 4 import java.util.ArrayList; 5 import java.util.Collections; 6 import java.util.Comparator; 7 import java.util.

探索推荐引擎内部的秘密,第 2 部分: 深入推荐引擎相关算法 - 协同过滤(转)

第 2 部分: 深入推荐引擎相关算法 - 协同过滤 本系列的第一篇为读者概要介绍了推荐引擎,下面几篇文章将深入介绍推荐引擎的相关算法,并帮助读者高效的实现这些算法. 在现今的推荐技术和算法中,最被大家广泛认可和采用的就是基于协同过滤的推荐方法.它以其方法模型简单,数据依赖性低,数据方便采集 , 推荐效果较优等多个优点成为大众眼里的推荐算法“No.1”.本文将带你深入了解协同过滤的秘密,并给出基于 Apache Mahout 的协同过滤算法的高效实现.Apache Mahout 是 ASF 的一个

加密类型及其相关算法

在互联网通信过程中,如何保证数据的安全性? 在通信过程中,数据安全主要从三个方面考虑:机密性(数据的内容不能被窃取) 完整性(数据的内容不能被修改) 身份验证(确定通信双方的身份) 加密类型:1.对称加密,加密和解密使用同一个密钥,但是密钥如何安全传输比较重要,对称加密数度较快,适于加密数据 2.单向加密,提取数据指纹,主要用于保证数据的完整性 单向加密的特点:输入相同则输出一定相同 雪崩效应:输入的微小改变会引起结果的巨大反差 定长输出 3.非对称加密,使用一对密钥(public-key和pr

探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类

聚类分析 什么是聚类分析? 聚类 (Clustering) 就是将数据对象分组成为多个类或者簇 (Cluster),它的目标是:在同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别较大.所以,在很多应用中,一个簇中的数据对象可以被作为一个整体来对待,从而减少计算量或者提高计算质量. 其实聚类是一个人们日常生活的常见行为,即所谓"物以类聚,人以群分",核心的思想也就是聚类.人们总是不断地改进下意识中的聚类模式来学习如何区分各个事物和人.同时,聚类分析已经广泛的应用在许多应用中,包

二叉树的创建、遍历

二叉树的创建.这里采用最简单的情况,创建完全二叉树,用数组来保存: 1 struct TreeNode 2 { 3 int val; 4 TreeNode *left, *right; 5 TreeNode(int x): val(x), left(NULL), right(NULL) {}; 6 }; 7 8 void CreatTree(TreeNode *root, int idx, int A[], int n) //root结点已分配,idx为根结点的编号 9 { 10 if(2 *