二叉树

二叉树:一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

特点:  1、每个节点最多有两颗子树        2、二叉树是有序树,即左右子树的顺序不能颠倒

数据结构种的二叉树:(5种)

特殊的二叉树:   满二叉树、完全二叉树、平衡二叉树

存储结构: 顺序(只适用于完全二叉树---堆)、 链式两种存储方式
三种遍历方式:前序(根、左、右)、中序(左、根、右)、后序(左、右、根)

接口实现

#pragma once
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
typedef char DataType;
typedef struct BTNode {
	char value;
	struct BTNode* left;		// 左孩子,同时代表着整棵左子树
	struct BTNode* right;		// 右孩子,同时代表着整棵右子树
} BTNode;

typedef struct {
	BTNode* btNode;		// 创建出树的根节点
	int used;			// 使用了的节点个数
}	Result;		// 创建二叉树的结构体返回值

BTNode* Create(DataType value);
Result CreateTree(DataType* preorder, int size);

void Preorder(BTNode* root);
void Inorder(BTNode* root);
void Postorder(BTNode* root);

int Size(BTNode* root);
int leafSize(BTNode* root);
int Height(BTNode* root);
int KLevelSize(BTNode* root, int k);

BTNode* Find(BTNode* root, DataType value);

int isSame(BTNode* p, BTNode* q);

int isSymmetric(BTNode* root);

int isSubTree(BTNode* p, BTNode* q);
#include "BinaryTree.h"
// 前序遍历
void Preorder(BTNode* root) {
	if (root == NULL) {
		return;
	}	// 树不存在
	printf("%c ", root->value);		// 根
	Preorder(root->left);	// 左子树
	Preorder(root->right);	// 右子树
}
void Inorder(BTNode* root){
	if (root == NULL) {
		return;
	}
	Inorder(root->left);	// 左子树
	printf("%c ", root->value);		// 根
	Inorder(root->right);	// 右子树
}
void Postorder(BTNode* root) {
	if (root == NULL) {
		return;
	}
	Postorder(root->left);		// 左子树
	Postorder(root->right);		// 右子树
	printf("%c ", root->value);		// 根
}
// 遍历的方式
//int count = 0;
//void Size(BTNode* root) {
//	if (root == NULL) {
//		return;
//	}
//	count++;
//	Size(root->left);
//	Size(root->right);
//}

// 递推的方式
int Size(BTNode* root) {
	if (root == NULL) {
		return 0;
	}
	int left = Size(root->left);	  // 左子树的节点总数
	int right = Size(root->right);	  // 右子树的节点总数
	return left + right + 1;
}
// 求叶子节点个数
int leafSize(BTNode* root) {
	if (root == NULL) {
		return 0;
	}
	if (root->left == NULL && root->right == NULL) {
		return 1;
	}	// 左右孩子都为空表示叶子节点
	int left = leafSize(root->left);
	int right = leafSize(root->right);
	return left + right;
}
// 高度
int Height(BTNode* root) {
	if (root == NULL) {
		return 0;
	}
	int left = Height(root->left);
	int right = Height(root->right);
	return (left > right ? left : right) + 1;
}
int KLevelSize(BTNode* root, int k) {
	if (root == NULL) {
		return 0;
	}
	if (k == 1) {
		return 1;
	}
	int left = KLevelSize(root->left, k - 1);
	int right = KLevelSize(root->right, k - 1);
	return left + right;
}
BTNode* Find(BTNode* root, DataType value) {
	if (root == NULL) {
		return NULL;
	}
	
	if (root->value == value) {
		return root;
	}
	BTNode* result = Find(root->left, value);	// 在左子树中找
	if ( result != NULL) {
		return result;
	}
	return Find(root->right, value);
	/*
	result = Find(root->right, value);		// 在右子树中找
	if (result != NULL) {
		return result;
	}
	return NULL;
	*/
}

int isSame(BTNode* p, BTNode* q) {
	if (p == NULL && q == NULL) {
		return 1;
	}
	if (p == NULL || q == NULL) {
		return 0;
	}

	return (p->value == q->value) && isSame(p->left, q->left) && isSame(p->right, q->right);
}
// 判断两个树是否对称
int _isMirror(BTNode* p, BTNode* q) {	
	if (p == NULL && q== NULL) {
		return 1;
	}
	if (p == NULL || q == NULL) {
		return 0;
	}
	return p->value == q->value && _isMirror(p->left, q->right) && _isMirror(p->right, q->left);
}
// 判断某个树是否为镜像树, 左右子树对称
int isSymmetric(BTNode* root) {
	if (root == NULL) {
		return 1;
	}
	return _isMirror(root->left, root->right);
}
// 判断q是否为p的子树
int preorder(BTNode* r, BTNode* s) {
	if (r == NULL) {
		return 0;
	}
	if (isSame(r, s)) {
		return 1;
	}
	int result = preorder(r->left, s);
	if (result) {	// 找到了
		return result;
	}
	return preorder(r->right, s);
	/*
	result = preorder(r->right, s);
	return result;
	*/
}
int isSubTree(BTNode* p, BTNode* q) {
	return preorder(p, q);
}


// 创建一个二叉节点
BTNode* Create(DataType value) {
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL) {
		printf("动态内存分配失败");
		return NULL;
	}
	node->value = value;
	node->left = node->right = NULL;
	return node;
}

// 根据前序遍历构建二叉树
Result CreateTree(DataType* preorder, int size) {
	if (size == 0) {
		Result r = { NULL, 0 };
		return r;
	}
	if (preorder[0] == '#') {
		Result r = { NULL, 1 };
		return r;
	}

	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL) {
		printf("内存分配失败");
		Result r = { NULL, -1 };
		return r;
	}
	root->value = preorder[0];
	Result left = CreateTree(preorder + 1, size - 1);
	root->left = left.btNode;

	Result right = CreateTree(preorder + 1 + left.used, size - 1 - left.used);
	root->right = right.btNode;

	Result r = { root, 1 + left.used + right.used };
	return r;
}
#include "BinaryTree.h"

int main() {
	char arr[] = "ABD##E#H##CF##G";
	int len = strlen(arr);
	Result r = CreateTree(arr, len);
	int b = r.btNode->value;

	/*BTNode* res = Search(a, 'K');
	 printf(" 高度: %d", Height(a));
	 printf(" 节点个数: %d", Size(a));
	 printf(" 叶子节点个数: %d", leafSize(a));
	 printf(" 第k层节点个数: %d", KLevelSize(a, 4));*/
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值