树
有一个特殊的结点,称为根结点,根节点没有前驱结点
除根节点外,其余结点被分成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;
}
测试结果:
二叉树中使用队列的方法可见:
队列操作
二叉树中使用栈的方法可见:栈操作
177万+

被折叠的 条评论
为什么被折叠?



