数据结构-------二叉树的基本性质(c语言实现先序遍历、中序遍历、后序遍历、层序遍历、求节点个数等)

二叉树的定义

一个有穷的节点集合

二叉树的特征

  1. 每个节点最多只有两棵子树
  2. 每棵子树有左右之分,其次序不能颠倒,是有序数

二叉搜索树

定义:一棵二叉树,可以为空;如果不为空,满足以下性质:

  1. 非空左子树的所有值小于其根节点的键值
  2. 非空右子树的所有值大于其根节点的键值
  3. 左右子树都是搜索二叉树

平衡二叉树

空树或者任一节点左、右子树高度差的绝对值不超过1

二叉树的重要性质

  1. 在二叉树的第i层上至多有 2^(i-1)个节点
  2. 深度为k的二叉树上至多含有2^k-1(k>=1)个节点
  3. 对任意一棵二叉树,若它含有n0个叶子节点、n2个度为2的节点,则必存在n0 = n2+1
  4. 具有 n 个结点的完全二叉树的深度为 [ log2n]+1 ([ log2n]:表示以2为底,对n取对数,并向下取整)
  5. 若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点:
    (1) 若 i=1,则该结点是二叉树的根,无双亲;否则,编号为 [i/2] 的结点为其双亲结点;
    (2) 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;
    (3) 若 2i+1>n,则该结点无右孩子结点,否则,编号为2i+1 的结点为其右孩子结点。

二叉树的创建

Node * CreatBiTree() {
	//先序创建二叉树
	char ch;
	scanf("%c", &ch);
	if (ch=='#')
	{
		return NULL;
	}
	else {
		Node *T = (Node *)malloc(sizeof(Node));
		T->data = ch;
		T->lchild = CreatBiTree();
		T->rchild = CreatBiTree();
		return T;
	}
}

二叉树的先序遍历

void PreOrderTraverse(Node *T) {
	//先序遍历
	if (T)
	{
		printf("%2c ", T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}

二叉树的中序遍历

void MidOrderTraverse(Node *T) {
	//中序遍历
	if (T)
	{
		
		MidOrderTraverse(T->lchild);
		printf("%2c ", T->data);
		MidOrderTraverse(T->rchild);
	}
}

二叉树的后序遍历

void LaOrderTraverse(Node *T) {
	//后序遍历
	if (T)
	{

		LaOrderTraverse(T->lchild);
		LaOrderTraverse(T->rchild);
		printf("%2c ", T->data);
	}
}

二叉树的层序遍历

/**
层序遍历要结合队列的出队,入队来写*/
void LevelOrderTraversal(Queue *q, struct node *root) {
	//层次遍历,边进边出
	struct node *temp;
	Push(q, root);
	while (!empty(q))
	{
		temp = Pop(q);
		printf("%2c", temp->data);
		if (temp->lchild)
		{
			Push(q, temp->lchild);
		}
		if (temp->rchild)
		{
			Push(q, temp->rchild);
		}
	}

二叉树的深度

int countDepth(Node *t) {
	//求二叉树的深度
	if (t==NULL)
	{
		return 0;
	}
	else if (t->lchild == NULL && t->rchild == NULL) {
		return 1;
	}
	else {
		int depth1 = countDepth(t->lchild) ;
		int depth2 = countDepth(t->rchild) ;
		return depth1 > depth2 ? depth1 + 1 : depth2 + 1;
	}
}

二叉树的节点数目

int countNode(Queue *q, struct node *root) {
	//通过对队列的遍历求节点数目

	struct node *temp;
	Push(q, root);
	int num = 0;
	while (!empty(q))
	{
		temp = Pop(q);
		num++;
		if (temp->lchild)
		{
			Push(q, temp->lchild);
		}
		if (temp->rchild)
		{
			Push(q, temp->rchild);
		}
	}
	return num;
}



复制二叉树

//二叉树的复制
Node *CopyTree(Node *T) {
	Node *t = (Node *)malloc(sizeof(Node));
	if (T == NULL) {
		t = NULL;
		return t;
	}
	else {
		t->data = T->data;
		t->lchild = CopyTree(T->lchild);
		t->rchild = CopyTree(T->rchild);
		return t;
	}
}

二叉树叶子节点的数目

int CountLeaf(Node *t) {//叶子节点的数目
	static int num = 0;
	if (t == NULL) {
		return 0;
	}
	else {
		if (t->lchild==NULL&&t->rchild==NULL)
		{
			num++;
		}
		CountLeaf(t->lchild);
		CountLeaf(t->rchild);
	}
	return num;
}




//统计叶子节点
void CountLeaf(Node *T) {
	if (T == NULL) {
		return ;
	}

	else {
		if (T->lchild == NULL && T->rchild == NULL) {
			printf("%2c ", T->data);
		}
		CountLeaf(T->lchild);
		CountLeaf(T->rchild);
	}
}

全部代码

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<malloc.h>
#define max 100
typedef struct node {
	char data;
	struct node *lchild, *rchild;
}Node;
typedef struct queue {
	struct node * num[max];
	int front;
	int rear;
}Queue;
Queue * initilize() {
	Queue *q = (Queue*)malloc(sizeof(Queue));
	q->front = 0;
	q->rear = 0;
	return q;//初始化队列
}
void Push(Queue *q, struct node *root) {
	q->num[++q->rear] = root;//入队
}
struct node *Pop(Queue *q) {
	return q->num[++q->front];//出队
}
bool empty(Queue *q) {
	return q->front == q->rear;//判断队列是否为空
}
Node * CreatBiTree() {
	//先序创建二叉树
	char ch;
	scanf("%c", &ch);
	if (ch=='#')
	{
		return NULL;
	}
	else {
		Node *T = (Node *)malloc(sizeof(Node));
		T->data = ch;
		T->lchild = CreatBiTree();
		T->rchild = CreatBiTree();
		return T;
	}
}
void PreOrderTraverse(Node *T) {
	//先序遍历
	if (T)
	{
		printf("%2c ", T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}
void MidOrderTraverse(Node *T) {
	//中序遍历
	if (T)
	{
		
		MidOrderTraverse(T->lchild);
		printf("%2c ", T->data);
		MidOrderTraverse(T->rchild);
	}
}
void LaOrderTraverse(Node *T) {
	//后序遍历
	if (T)
	{

		LaOrderTraverse(T->lchild);
		LaOrderTraverse(T->rchild);
		printf("%2c ", T->data);
	}
}
void LevelOrderTraversal(Queue *q, struct node *root) {
	//层次遍历,边进边出
	struct node *temp;
	Push(q, root);
	while (!empty(q))
	{
		temp = Pop(q);
		printf("%2c", temp->data);
		if (temp->lchild)
		{
			Push(q, temp->lchild);
		}
		if (temp->rchild)
		{
			Push(q, temp->rchild);
		}
	}
}
int countDepth(Node *t) {
	//求二叉树的深度
	if (t==NULL)
	{
		return 0;
	}
	else if (t->lchild == NULL && t->rchild == NULL) {
		return 1;
	}
	else {
		int depth1 = countDepth(t->lchild) ;
		int depth2 = countDepth(t->rchild) ;
		return depth1 > depth2 ? depth1 + 1 : depth2 + 1;
	}
}
int countNode(Queue *q, struct node *root) {
	//通过对队列的遍历求节点数目

	struct node *temp;
	Push(q, root);
	int num = 0;
	while (!empty(q))
	{
		temp = Pop(q);
		num++;
		if (temp->lchild)
		{
			Push(q, temp->lchild);
		}
		if (temp->rchild)
		{
			Push(q, temp->rchild);
		}
	}
	return num;
}
int CountLeaf(Node *t) {//叶子节点的数目
	static int num = 0;
	if (t == NULL) {
		return 0;
	}
	else {
		if (t->lchild==NULL&&t->rchild==NULL)
		{
			num++;
		}
		CountLeaf(t->lchild);
		CountLeaf(t->rchild);
	}
	return num;
}
int main() {
	printf("先序遍历输入:");
	Node *T = CreatBiTree();
	printf("先序遍历输出:\n");
	PreOrderTraverse(T);
	printf("\n");
	printf("中序遍历输出:\n");
	MidOrderTraverse(T);
	printf("\n");
	printf("后序遍历输出:\n");
	LaOrderTraverse(T);
	printf("\n");
	printf("层次遍历输出:\n");
	Queue *q = initilize();
	LevelOrderTraversal(q, T);
	printf("\n");
	printf("树的深度为:%d\n", countDepth(T));
	printf("节点的数目为:%d\n", countNode(q,T));
	printf("叶子节点的数目为:%d\n", CountLeaf(T));
}


测试结果

在这里插入图片描述

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何一平?

你的收获就是我学习的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值