二叉树的实现和操作

目录

二叉树定义

特殊类型

满二叉树

完全二叉树

代码实现

定义二叉树

前序遍历创建二叉树

前序遍历

中序遍历

后序遍历

获取树的深度

获取叶节点的个数

判断满二叉树

判断对称二叉树

在树中查找值为val的结点

整体代码


二叉树定义

       二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。

特殊类型

满二叉树

如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树   

完全二叉树

深度为k,有n个节点的二叉树当且仅当其每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完全二叉树  。

完全二叉树的特点是叶子节点只可能出现在层序最大的两层上,并且某个节点的左分支下子孙的最大层序与右分支下子孙的最大层序相等或大1  。

代码实现

定义二叉树

typedef char ElemType;
typedef struct BinaryTree {
	ElemType val;		//值
	struct BinaryTree* left;	//左子树
	struct BinaryTree* right;	//右子树
}BinaryTree;

前序遍历创建二叉树

/// <summary>
/// 创建二叉树
/// </summary>
/// <param name="str">对应的序列</param>
/// <param name="pi">指向下标的指针</param>
/// <param name="n">序列的长度</param>
/// <returns>返回创建的树</returns>
BinaryTree* Create(const char* str, int* pi, int n) {
	if (*pi >= n || str[*pi] == '#') {
		++* pi;
		return NULL;
	}
	BinaryTree* root = (BinaryTree*)malloc(sizeof(BinaryTree));
	assert(root);
	root->val = str[*pi];
	++* pi;
	root->left = Create(str, pi, n);
	root->right = Create(str, pi, n);
	return root;
}

前序遍历

void PreOrder(BinaryTree* root) {
	if (!root) {
		printf("null ");
		return;
	}
	printf("%c ", root->val);
	PreOrder(root->left);
	PreOrder(root->right);
}

中序遍历

void InOrder(BinaryTree* root) {
	if (!root) {
		printf("null ");
		return;
	}
	PreOrder(root->left);
	printf("%c ", root->val);
	PreOrder(root->right);
}

后序遍历

void PostOrder(BinaryTree* root) {
	if (!root) {
		printf("null ");
		return;
	}
	PreOrder(root->left);
	PreOrder(root->right);
	printf("%c ", root->val);
}

获取树的深度

int Depth(BinaryTree* root) {
	if (!root) {
		return 0;
	}
	int left = Depth(root->left);
	int right = Depth(root->right);
	int high = left > right ? left : right;
	return high + 1;
}

获取叶节点的个数

int CountOfLeves(BinaryTree* root) {
	if (!root) {
		return 0;
	}
	if (!root->left && !root->right) {
		return 1;
	}
	return CountOfLeves(root->left) + CountOfLeves(root->right);

}

判断满二叉树

对于满二叉树,其深度和叶节点符合2的深度减1次方等于叶节点的个数

 

bool IsFull(BinaryTree* root) {
	int depth = Depth(root);
	int leves = Depth(root);
	return pow(2, depth - 1) == leves;
}

判断对称二叉树

对称二叉树:

 从父节点将左右节点分开,左右节点相互对称

bool isSame(BinaryTree* left, BinaryTree* right) {
	if (!left && !right) {
		return true;
	}
	if (!left || !right) {
		return false;
	}
	if (left->val == right->val) {
		return isSame(left->right, right->left) && isSame(left->left, right->right);
	}
	return false;

}

bool IsSymmetic(BinaryTree* root) {
	if (!root) {
		return true;
	}
	return isSame(root->left, root->right);
}

在树中查找值为val的结点

BinaryTree* FindTree(BinaryTree* root, ElemType val) {
	if (!root) {
		return NULL;
	}
	if (root->val == val) {
		return root;
	}
	BinaryTree* tmp = FindTree(root->left, val);
	if (tmp != NULL) {
		return tmp;
	}
	tmp = FindTree(root->right, val);
	if (tmp != NULL) {
		return tmp;
	}
	return NULL;
}

整体代码

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <math.h>
typedef char ElemType;
typedef struct BinaryTree {
	ElemType val;		//值
	struct BinaryTree* left;	//左子树
	struct BinaryTree* right;	//右子树
}BinaryTree;

/// <summary>
/// 创建二叉树
/// </summary>
/// <param name="str">对应的序列</param>
/// <param name="pi">指向下标的指针</param>
/// <param name="n">序列的长度</param>
/// <returns>返回创建的树</returns>
BinaryTree* Create(const char* str, int* pi, int n) {
	if (*pi >= n || str[*pi] == '#') {
		++* pi;
		return NULL;
	}
	BinaryTree* root = (BinaryTree*)malloc(sizeof(BinaryTree));
	assert(root);
	root->val = str[*pi];
	++* pi;
	root->left = Create(str, pi, n);
	root->right = Create(str, pi, n);
	return root;
}
//前序遍历
void PreOrder(BinaryTree* root) {
	if (!root) {
		printf("null ");
		return;
	}
	printf("%c ", root->val);
	PreOrder(root->left);
	PreOrder(root->right);
}
//中序遍历
void InOrder(BinaryTree* root) {
	if (!root) {
		printf("null ");
		return;
	}
	PreOrder(root->left);
	printf("%c ", root->val);
	PreOrder(root->right);
}
//后序遍历
void PostOrder(BinaryTree* root) {
	if (!root) {
		printf("null ");
		return;
	}
	PreOrder(root->left);
	PreOrder(root->right);
	printf("%c ", root->val);
}
//树的深度
int Depth(BinaryTree* root) {
	if (!root) {
		return 0;
	}
	int left = Depth(root->left);
	int right = Depth(root->right);
	int high = left > right ? left : right;
	return high + 1;
}

//叶节点的个数
int CountOfLeves(BinaryTree* root) {
	if (!root) {
		return 0;
	}
	if (!root->left && !root->right) {
		return 1;
	}
	return CountOfLeves(root->left) + CountOfLeves(root->right);

}

//判断是不是满二叉树
bool IsFull(BinaryTree* root) {
	int depth = Depth(root);
	int leves = Depth(root);
	return pow(2, depth - 1) == leves;
}

bool isSame(BinaryTree* left, BinaryTree* right) {
	if (!left && !right) {
		return true;
	}
	if (!left || !right) {
		return false;
	}
	if (left->val == right->val) {
		return isSame(left->right, right->left) && isSame(left->left, right->right);
	}
	return false;

}

//判断是否是对称二叉树
bool IsSymmetic(BinaryTree* root) {
	if (!root) {
		return true;
	}
	return isSame(root->left, root->right);
}

BinaryTree* FindTree(BinaryTree* root, ElemType val) {
	if (!root) {
		return NULL;
	}
	if (root->val == val) {
		return root;
	}
	BinaryTree* tmp = FindTree(root->left, val);
	if (tmp != NULL) {
		return tmp;
	}
	tmp = FindTree(root->right, val);
	if (tmp != NULL) {
		return tmp;
	}
	return NULL;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值