树的定义与操作

    有一个特殊的结点,称为根结点,根节点没有前驱结点
    除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似 的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。
    树是递归定义的。
二叉树
    一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成。

特点:

     每个结点最多有两棵子树,即二叉树不存在度大于2的结点
    二叉树的子树有左右之分,其子树的次序不能颠倒
满二叉树:
    在一棵二叉树中,如果所有分支结点都存在左子树和右子树, 并且所有叶子节点都在同一层上
完全二叉树:
    如果一棵具有N个结点的二叉树的结构与满二叉树的前N个 结点的结构相同,称为完全二叉树

链式存储二叉树的操作
#pragma once

#include<stdio.h>

typedef char DataType;

typedef struct BinTreeNode{
	struct BinTreeNode * pLeft;
	struct BinTreeNode * pRight;
	DataType data;
}BinTreeNode;
#include "BinTree.h"
#include "Queue.h"
#include "Stack.h"

BinTreeNode * CreateRoot(DataType data)
{
	BinTreeNode *pRoot = (BinTreeNode *)malloc(sizeof(BinTreeNode));
	assert(pRoot);
	pRoot->pLeft = NULL;
	pRoot->pRight = NULL;
	pRoot->data = data;

	return pRoot;
}

BinTreeNode * CreateTree(DataType preOrder[], int size, int *pIndex)
{
	if (*pIndex >= size){
		return NULL;
	}
	if (preOrder[*pIndex] == '#'){
		*pIndex += 1;
		return NULL;
	}

	BinTreeNode *pRoot = CreateRoot(preOrder[*pIndex]);
	*pIndex += 1;
	pRoot->pLeft = CreateTree(preOrder, size, pIndex);
	pRoot->pRight = CreateTree(preOrder, size, pIndex);

	return pRoot;
}

BinTreeNode * CreateTree2(DataType **str)
{
	if (!**str){
		return NULL;
	}
	if (**str == '#'){
		(*str)++;
		return NULL;
	}

	BinTreeNode *pRoot = CreateRoot(**str);
	(*str)++;
	pRoot->pLeft = CreateTree2(str);
	pRoot->pRight = CreateTree2(str);

	return pRoot;
}

//前序遍历
void PreOrder(BinTreeNode *pRoot)
{
	if (!pRoot){
		return;
	}
	
	printf("%c ", pRoot->data);
	PreOrder(pRoot->pLeft);
	PreOrder(pRoot->pRight);
}

//非递归前序遍历
void PreOrderR(BinTreeNode *pRoot)
{
	BinTreeNode *pCur = pRoot;
	BinTreeNode *pTop = NULL;
	Stack stack;
	StackInit(&stack);

	while (pCur || !StackIsEmpty(&stack)){
		while (pCur){
			printf("%c ", pCur->data);
			StackPush(&stack, pCur);
			pCur = pCur->pLeft;
		}
		pTop = StackTop(&stack);
		StackPop(&stack);

		pCur = pTop->pRight;
	}
	printf("\n");
}

//中序遍历
void InOrder(BinTreeNode *pRoot)
{
	if (!pRoot){
		return;
	}

	InOrder(pRoot->pLeft);
	printf("%c ", pRoot->data);
	InOrder(pRoot->pRight);
}

//非递归中序遍历
void InOrderR(BinTreeNode *pRoot)
{
	BinTreeNode *pCur = pRoot;
	BinTreeNode *pTop = NULL;
	Stack stack;
	StackInit(&stack);

	while (pCur || !StackIsEmpty(&stack)){
		while (pCur){
			StackPush(&stack, pCur);
			pCur = pCur->pLeft;
		}
		pTop = StackTop(&stack);
		printf("%c ", pTop->data);
		StackPop(&stack);

		pCur = pTop->pRight;
	}
	printf("\n");
}

//后序遍历
void BackOrder(BinTreeNode *pRoot)
{
	if (!pRoot){
		return;
	}

	BackOrder(pRoot->pLeft);
	BackOrder(pRoot->pRight);
	printf("%c ", pRoot->data);
}

//非递归后序遍历
void BackOrderR(BinTreeNode *pRoot)
{
	BinTreeNode *pCur = pRoot;
	BinTreeNode *pTop = NULL;
	BinTreeNode *pLast = NULL;

	Stack stack;
	StackInit(&stack);

	while (pCur || !StackIsEmpty(&stack)){
		while (pCur){
			StackPush(&stack, pCur);
			pCur = pCur->pLeft;
		}

		pTop = StackTop(&stack);
		if (!pTop->pRight || pTop->pRight == pLast){
			printf("%c ", pTop->data);
			StackPop(&stack);
			pLast = pTop;
			continue;
		}

		pCur = pTop->pRight;
	}
	printf("\n");
}

//二叉树的高度
int GetHight(BinTreeNode *pRoot)
{
	if (!pRoot){
		return 0;
	}
	int left = GetHight(pRoot->pLeft);
	int right = GetHight(pRoot->pRight);

	return left > right ? left + 1 : right + 1;
}

//总结点个数
int GetSize(BinTreeNode *pRoot)
{
	if (!pRoot){
		return 0;
	}
	return GetSize(pRoot->pLeft) + GetSize(pRoot->pRight) + 1;
}

//叶子结点个数
int GetLeafSize(BinTreeNode *pRoot)
{
	if (!pRoot){
		return 0;
	}
	if (!pRoot->pLeft && !pRoot->pRight){
		return 1;
	}
	return GetLeafSize(pRoot->pLeft) + GetLeafSize(pRoot->pRight);
}

//第k层结点个数
int GetLevelSize(BinTreeNode *pRoot, int k)
{
	assert(k >= 1);
	if (!pRoot){
		return 0;
	}
	if (k == 1){
		return 1;
	}
	return GetLevelSize(pRoot->pLeft, k - 1) + GetLevelSize(pRoot->pRight, k - 1);
}

//查找结点
BinTreeNode * FindNode(BinTreeNode *pRoot, int n)
{
	if (!pRoot){
		return NULL;
	}
	if (pRoot->data == n){
		return pRoot;
	}
	BinTreeNode * newNode = FindNode(pRoot->pLeft, n);
	if (newNode){
		return newNode;
	}
	return FindNode(pRoot->pRight, n);
}

//层序遍历
void LevelOrder(BinTreeNode *pRoot)
{
	if (!pRoot){
		return;
	}

	Queue queue;
	BinTreeNode *pFront;
	QueueInit(&queue);
	QueuePush(&queue, pRoot);
	while (!QueueIsEmpty(&queue)){
		pFront = QueueFront(&queue);
		QueuePop(&queue);
		printf("%c ", pFront->data);
		if (pFront->pLeft){
			QueuePush(&queue, pFront->pLeft);
		}
		if (pFront->pRight){
			QueuePush(&queue, pFront->pRight);
		}
	}
	printf("\n");
}

//判断是否为完全二叉树
int IsPrefectBinTree(BinTreeNode *pRoot)
{
	if (!pRoot){
		return 1;
	}
	Queue queue;
	BinTreeNode *pFront;
	QueueInit(&queue);
	QueuePush(&queue, pRoot);

	while (1){
		pFront = QueueFront(&queue);
		QueuePop(&queue);
		if (!pFront){
			break;
		}
		QueuePush(&queue, pFront->pLeft);
		QueuePush(&queue, pFront->pRight);
	}

	while (!QueueIsEmpty(&queue)){
		pFront = QueueFront(&queue);
		if (pFront){
			return -1;
		}
		QueuePop(&queue);
	}
	return 1;
}

int main()
{
	DataType * preOrder = "ABD###CE##F";
	int index = 0;
	BinTreeNode *pRoot = CreateTree(preOrder, strlen(preOrder), &index);

	/*PreOrder(pRoot); 
	printf("\n");
	InOrder(pRoot); 
	printf("\n");
	BackOrder(pRoot); 
	printf("\n");*/

	/*PreOrderR(pRoot);
	InOrderR(pRoot);
	BackOrderR(pRoot);*/

	/*LevelOrder(pRoot);
	printf("%d\n", IsPrefectBinTree(pRoot));*/

	printf("%d\n", GetHight(pRoot));
	printf("%d\n", GetSize(pRoot));
	printf("%d\n", GetLeafSize(pRoot));
	printf("%d\n", GetLevelSize(pRoot, 2));

	printf("%p\n", FindNode(pRoot, 'B'));
	system("pause");
	return 0;
}

测试结果:
二叉树中使用队列的方法可见: 队列操作
二叉树中使用栈的方法可见:栈操作
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值