您的位置:首页 > 其它

二叉树的创建和相关算法

2016-05-29 15:37 337 查看
 


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

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;
}

如果上述叙述有相关问题请大家能指出,本人邮箱:597995302@qq.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: