树的认识与理解

二叉树的概念及结构
1.概念:

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

二叉树的特点:

	1.每个结点最多有两颗子树,即二叉树不存在度大于2的结点
	2.二叉树的子树有左右之分,其子树的次序不能颠倒。

2.二叉树的结构
特殊的二叉树:

		1.满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。若一个二叉树的层数为K,且结点总数是(2^K)-1;则称它是满二叉树
		2.完全二叉树:完全二叉树失效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点——对应时称之为完全二叉树。*要注意的是满二叉树是一种特殊的完全二叉树*

在这里插入图片描述
在这里插入图片描述


//queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<stdbool.h>
//前置声明
struct BinaryTreeNode;
typedef struct BinaryTreeNode* Datatype;

typedef struct QueueNode
{
	struct QueueNode* next;
	Datatype data;
}QueueNode;
typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;

}Queue;
void QueueInit(Queue* pst);
void QueueDestroy(Queue* pst);
bool QueueEmpty(Queue* pst);
Datatype QueueBack(Queue* pst);
Datatype QueueFront(Queue* pst);
void QueuePush(Queue* pst, Datatype x);
void QueuePop(Queue* pst);
int QueueSize(Queue* pst);
#endif



//queue.cpp
#include"queue.h"

void QueueInit(Queue* pst)
{
	assert(pst);
	pst->head = pst->tail = NULL;
}
void QueueDestroy(Queue* pst)
{
	assert(pst);
	QueueNode* cur = pst->head;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pst->head = pst->tail = NULL;
}
bool QueueEmpty(Queue* pst) 
{
	assert(pst);
	return pst->head == NULL;
}
Datatype QueueBack(Queue* pst)
{
	assert(pst);
	assert(!QueueEmpty(pst));
	return pst->tail->data;
}
Datatype QueueFront(Queue* pst)
{
	assert(pst);
	assert(!QueueEmpty(pst));
	return pst->head->data;
}
void QueuePush(Queue* pst, Datatype x)
{
	assert(pst);
	QueueNode*
 newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		printf("malloc error!\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pst->head == NULL)
	{
		pst->head = pst->tail = newnode;
	}
	else
	{
		pst->tail->next = newnode;
		pst->tail = newnode;
	}
}
void QueuePop(Queue* pst)
{
	assert(pst);
	assert(!QueueEmpty(pst));
	if (pst->head->next == NULL)
	{
		free(pst->head);
		pst->head = pst->tail = NULL;
	}
	else
	{
		QueueNode* next = pst->head->next;

		free(pst->head);
		pst->head = next;
	}
	



}

int QueueSize(Queue* pst)
{
	assert(pst);
	int num = 0;
	QueueNode* cur = pst->head;
	
	
		
		while (cur)
		{
			num++;
			cur = cur->next;
		}
	
	return num;
}









//tree.cpp
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"queue.h"

typedef char BTDataType;
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
	BTDataType data;
}BTNode;

void PrevOrder(BTNode* root)//前序
{
	if (root == NULL)
	{
		//printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	PrevOrder(root->_left);
	PrevOrder(root->_right);
}
void InOrder(BTNode* root)//中序
{
	if (root == NULL)
	{
		//printf("NULL ");
		return;
	}
	
	InOrder(root->_left);
	printf("%c ", root->data);
	InOrder(root->_right);
}



void PostOrder(BTNode* root)//后序
{
	if (root == NULL)
	{
		//printf("NULL ");
		return;
	}
	
	PostOrder(root->_left);
	PostOrder(root->_right);
	printf("%c ", root->data);
}
//思路一:遍历计数的方式
//void TreeSize(BTNode* root,int* psize)
//{
//	if (root == NULL)
//	{
//		//printf("NULL ");
//		return;
//	}	
//	++(*psize);
//	TreeSize(root->_left, psize);
//	TreeSize(root->_right, psize);
//}




//子问题拆解     空:0    非空 = 左子树节点个数 + 右子树节点个数 + 1;
//分治算法: 大问题拆解成子问题
int  TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->_left) + TreeSize(root->_right) + 1;
}

BTNode* CreateTreeNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	node->data = x;
	node->_left = NULL;
	node->_right = NULL;
	return node;
}

int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	if (root->_left == NULL && root->_right == NULL)
	{
		return 1;
	}
	return TreeLeafSize(root->_left) + TreeLeafSize(root->_right);
}

//k>0
int TreeKLevelSize(BTNode* root, int k)
{
	assert(k > 0);
	//求当前树的第K层的节点个数 = 左子树K-1层的节点个数 + 右子树K-1层的节点个数
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;
	--k;
	return TreeKLevelSize(root->_left, k) + TreeKLevelSize(root->_right, k);
	
}

BTNode* TreeFind(BTNode* root, BTDataType x)
{
	//查找树里面值为x的那个节点
	//1.root == NULL return NULL
	//2.root节点不是我们要找的,先到左树去找,左树如果没有,再到右树去找,左右都没有
	//3.左右都没有,当前树没有找到返回NULL
	if (root == NULL)
		return NULL;
	if (root->data == x)
		return root;
	BTNode* lret = TreeFind(root->_left, x);
	if (lret)
		return lret;
	BTNode* rret = TreeFind(root->_right, x);
	if (rret)
		return rret;
	return NULL;
}

void BinaryTree_Destory(BTNode** pproot)
{
	if (*pproot == NULL)
		return;		
	BinaryTree_Destory(&(*pproot)->_left);
	BinaryTree_Destory(&(*pproot)->_right);

	free(*pproot);
	*pproot = NULL;
}


//树的销毁
void BinaryTree_Destory(BTNode* root)
{
	if (root == NULL)
		return;
	BinaryTree_Destory(root->_left);
	BinaryTree_Destory(root->_right);

	free(root);
	
}

//层序遍历
//void TreeLevelOrder(BTNode* root)
//{
//	Queue q;
//	QueueInit(&q);
//	if (root)
//	{
//		QueuePush(&q, root);
//	}
//	while (!QueueEmpty(&q))
//	{
//		BTNode* front = QueueFront(&q);
//		printf("%c ", front->data);
//		QueuePop(&q);
//
//		if (front->_left)
//		QueuePush(&q, front->_left);
//		if (front->_right)
//			QueuePush(&q, front->_right);
//	}
//	QueueDestroy(&q);
//}
//


void TreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root == NULL)
		return;
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		printf("%c ", front->data);
		QueuePop(&q);
		if (front == NULL)
			break;
		if (front->_left)
			QueuePush(&q, front->_left);
		if (front->_right)
			QueuePush(&q, front->_right);

	}
	QueueDestroy(&q);
}



//判断是否是完全二叉树。
bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root == NULL)
		return true;
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)

		{
			QueuePush(&q, front->_left);
			QueuePush(&q, front->_right);
		}
		else
			break;
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)
			return false;
	}
	return true;
}
int main()
{
	BTNode* A = CreateTreeNode('A');
	BTNode* B = CreateTreeNode('B');
	BTNode* C = CreateTreeNode('C');
	BTNode* D = CreateTreeNode('D');
	BTNode* E = CreateTreeNode('E');
	BTNode* F = CreateTreeNode('F');
	A->_left = B;
	A->_right = C;
	B->_left = D;
	C->_left = E;
	C->_right = F;

	PrevOrder(A);
	printf("\n");

	InOrder(A);
	printf("\n");

	PostOrder(A);
	printf("\n");
	int size = 0;
	//TreeSize(A, &size);
	//printf("TreeSize: %d \n",size);
	//size = 0;
	//TreeSize(A, &size);
	//
	//printf("TreeSize: %d \n", TreeSize(A));
	//printf("TreeSize: %d \n", TreeSize(A));
	//printf("TreeLeafSize: %d \n", TreeLeafSize(A));

	printf("TreeKLevelSize: %d \n", TreeKLevelSize(A, 3));
	BTNode* p = TreeFind(A, 'c');

	//销毁二叉树:后序遍历
	printf("BinaryTreeComplete: %d \n", BinaryTreeComplete(A));

	TreeLevelOrder(A);
	BinaryTree_Destory(A);
	A = NULL;
	system("pause");

	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

倚心

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值