树的表示方法以及先、中、后序遍历以及求叶子结点个数和树的深度代码C代码

树的概念及性质

暂时略

树的表示方法

图形表示法:直观清晰易于理解。

广义表表示法:不常用。

左孩子右兄弟表示法:可以将多叉树转化为二叉树的一种表示方法,而二叉树更适合计算机表示。(也就是说一般遇到多叉树,转化成二叉树)

二叉树及性质

二叉树的存储结构

顺序存储

用一个数组来存储二叉树,结合二叉树的性质,可以保存树的结点之间的关系。最适合完全二叉树和满二叉树,如果是一般二叉树,将导致存储空间浪费,最坏情况下是一颗右斜树。

链式存储

二叉链表示法:包含lchild、data、rchild

三叉链表示法:包含lchild、data、rchild和parent。这种表示方法记录了各个结点的父结点位置,增加了开销,但是便于查找父结点。

双亲表示法:包含data、parent、LRtag,数据域、父结点位置、是左孩子还是右孩子。实际开发中如果树不是太复杂,就选择这种表示方法。

树的先、中、后序递归遍历以及求叶子结点个数和树的深度代码

递归的方法

BitNode.h

#ifndef _BITNODE_H_
#define _BITNODE_H_
//用二叉链表示法表示树的数据结构
typedef struct BitNode
{
	char data;
	struct BitNode *lchild, *rchild;//左右孩子指针
}BitNode;
//typedef struct BitNode* BiTree;

void preOrder(BitNode *T);
void inOrder(BitNode *T);
void lastOrder(BitNode *T);
int getLeafNum(BitNode *T);
int Depth(BitNode *T);
#endif // !_BITNODE_H_

Operator.cpp

扫描二维码关注公众号,回复: 8487285 查看本文章
#include "BitNode.h"
#include<stdio.h>

void preOrder(BitNode *T)
{
	if (T == NULL)
		return;
	printf("%c", T->data);//输出根节点的值
	//遍历左子树
	if (T->lchild != NULL)
		preOrder(T->lchild);
	//遍历右子树
	if (T->rchild != NULL)
		preOrder(T->rchild);
}

void inOrder(BitNode *T)
{
	if (T == NULL)
		return;
	//遍历左子树
	if (T->lchild != NULL)
		inOrder(T->lchild);

	printf("%c", T->data);//输出根节点的值
	
	//遍历右子树
	if (T->rchild != NULL)
		inOrder(T->rchild);
}

void lastOrder(BitNode *T)
{
	if (T == NULL)
		return;
	//遍历左子树
	if (T->lchild != NULL)
		lastOrder(T->lchild);

	//遍历右子树
	if (T->rchild != NULL)
		lastOrder(T->rchild);

	printf("%c", T->data);//输出根节点的值

}

int getLeafNum(BitNode *T)
{
	static int sum = 0;
	if (T == NULL)
		return 0;
	if (T->lchild == NULL && T->rchild == NULL)//左右孩子均为空,就是叶子节点
		sum++;//叶子节点数+1
	getLeafNum(T->lchild);//获取左子树的叶子节点数
	getLeafNum(T->rchild);
	return sum;
}

int Depth(BitNode *T)
{
	int depth = 0;
	int ldepth = 0, rdepth = 0;
	if (T == NULL)
		return 0;
	ldepth = Depth(T->lchild);
	rdepth = Depth(T->rchild);
	return 1 + (ldepth > rdepth ? ldepth : rdepth);
}

main.cpp

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "BitNode.h"

int main()
{
	BitNode nodeA, nodeB, nodeD, nodeF, nodeI, nodeL;//创建6个结点
	//将结点空间初始化为空
	memset(&nodeA, 0, sizeof(BitNode));
	memset(&nodeB, 0, sizeof(BitNode));
	memset(&nodeD, 0, sizeof(BitNode));
	memset(&nodeF, 0, sizeof(BitNode));
	memset(&nodeI, 0, sizeof(BitNode));
	memset(&nodeL, 0, sizeof(BitNode));
	//给结点赋值
	nodeA.data = 'A';
	nodeB.data = 'B';
	nodeD.data = 'D';
	nodeF.data = 'F';
	nodeI.data = 'I';
	nodeL.data = 'L';
	//存储结点之间的关系
	nodeA.lchild = &nodeB;
	nodeA.rchild = &nodeD;
	nodeB.rchild = &nodeF;
	nodeF.lchild = &nodeL;
	nodeD.lchild = &nodeI;

	printf("二叉树构建成功!\n");
	printf("先序遍历:");
	preOrder(&nodeA);

	printf("\n中序遍历:");
	inOrder(&nodeA);

	printf("\n后序遍历:");
	lastOrder(&nodeA);

	printf("\n");
	printf("叶子结点个数:%d\n", getLeafNum(&nodeA));
	printf("树的高度:%d\n", Depth(&nodeA));
	system("pause");
	return 0;
}

非递归的方法

linkstack.h

#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
//二叉树的结点结构
typedef struct BitNode
{
	char data;//数据类型为char
	struct BitNode *lchild, *rchild;
}BitNode;
//栈的结点结构
typedef struct Node *pNode;
typedef struct Stack *LinkStack;
struct Node //数据结点
{
	BitNode * data; //数据,BitNode类型的指针
	pNode next;//指针
};

struct Stack
{
	pNode top; //栈顶元素指针
	int size; //栈大小
};

LinkStack Create();//创建栈
int IsEmpty(LinkStack lstack);//判断栈是否为空
int Push(LinkStack lstack, BitNode *val);//压栈
pNode getTop(LinkStack lstack);//获取栈顶元素
pNode Pop(LinkStack lstack);//弹出栈顶元素
#endif // !_LINKSTACK_H_

linkstack.cpp

#include "linkstack.h"
#include <stdio.h>
#include <stdlib.h>

LinkStack Create()//创建栈实际上就是先创建一个栈的头结点
{
	LinkStack lstack = (LinkStack)malloc(sizeof(struct Stack));
	if (lstack != NULL)
	{
		lstack->top = NULL;
		lstack->size = 0;
	}
	return lstack;
}

int IsEmpty(LinkStack lstack)
{
	if (lstack->top == NULL || lstack->size == 0)
		return 1;
	return 0;
}

int Push(LinkStack lstack, BitNode *val)
{
	pNode node = (pNode)malloc(sizeof(struct Node));//为val元素分配一个新的节点
	if (node != NULL)
	{
		node->data = val;
		node->next = getTop(lstack);
		lstack->top = node;
		lstack->size++;
	}
	return 1;
}

pNode getTop(LinkStack lstack)//获取栈顶元素
{
	if (lstack->size != 0)
		return lstack->top;
	return NULL;
}

pNode Pop(LinkStack lstack)
{
	if (IsEmpty(lstack))
	{
		return NULL;
	}
	pNode node = lstack->top; //node指向栈顶元素
	lstack->top = lstack->top->next; //top指向下一个元素
	lstack->size--;
	return node;
}

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkstack.h"

//寻找遍历起始点
BitNode * GoFarLeft(BitNode * T, LinkStack ls)
{
	if (T == NULL)
		return NULL;
	while (T->lchild != NULL)//左子树不为空,就一直向下寻找
	{
		Push(ls, T);
		T = T->lchild;
	}
	return T;
}

//非递归中序遍历函数
void MyOrder(BitNode * T)
{
	LinkStack ls = Create();
	BitNode * t = GoFarLeft(T, ls);//寻找遍历的起始点
	while (t != NULL)
	{
		printf("%c", t->data);//打印起始结点的值
		if (t->rchild != NULL)
			t = GoFarLeft(t->rchild, ls);//寻找右子树中的起始点
		else if (!IsEmpty(ls))//如果栈不为空
		{
			t = getTop(ls)->data;//回退到栈顶元素结点
			Pop(ls);//栈顶元素弹出
		}
		else
			t = NULL;
	}
}

int main()
{
	BitNode nodeA, nodeB, nodeD, nodeF, nodeI, nodeL;
	memset(&nodeA, 0, sizeof(BitNode));
	memset(&nodeB, 0, sizeof(BitNode));
	memset(&nodeD, 0, sizeof(BitNode));
	memset(&nodeF, 0, sizeof(BitNode));
	memset(&nodeI, 0, sizeof(BitNode));
	memset(&nodeL, 0, sizeof(BitNode));
	//给结点赋值
	nodeA.data = 'A';
	nodeB.data = 'B';
	nodeD.data = 'D';
	nodeF.data = 'F';
	nodeI.data = 'I';
	nodeL.data = 'L';
	//存储结点之间的逻辑关系
	nodeA.lchild = &nodeB;
	nodeA.rchild = &nodeD;
	nodeB.rchild = &nodeF;
	nodeF.lchild = &nodeL;
	nodeD.lchild = &nodeI;

	printf("构建二叉树成功!\n");
	printf("非递归中序遍历:\n");
	MyOrder(&nodeA);

	printf("\n");
	system("pause");
	return 0;
}
发布了12 篇原创文章 · 获赞 927 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/zcg_741454897/article/details/103575046
今日推荐