设计程序,利用二叉链表结构,建立一棵二叉树。并能递归实现二叉树的先序遍历、中序遍历和后序遍历三种遍历算法,能用队列实现二叉树的层次遍历算法,并按层次输出(标出层号),并能统计树叶数,结点数,层高等信息

(一)利用二叉链表结构,通过先序遍历先建立起一棵二叉树如图1-1。根据建立这个的二叉树,并且通过递归的方式实现了二叉树的先序遍历、中序遍历和后序遍历三种遍历算法,用队列实现二叉树的层次遍历算法,并按层次输出(标出层号),并能统计树叶数,结点数,层高等信息,如图1-2。

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30

// 定义一个字符类型别名,用于二叉树的元素类型
typedef char ElemType;
// 定义一个指向二叉树节点的指针类型别名
typedef struct TNode *BiTree;

// 定义二叉树节点的结构体
struct TNode
{
	char data; // 节点数据
	BiTree lchild; // 指向左子树的指针
	BiTree rchild; // 指向右子树的指针
};

// 判断二叉树是否为空
// 参数T是指向二叉树根的指针的指针
int IsEmpty_BiTree(BiTree *T)
{
    // 如果T指向的指针为NULL,说明二叉树为空
	if(*T == NULL)
	return 1; // 返回1,表示二叉树为空
	else
	return 0; // 返回0,表示二叉树不为空
}

// 创建二叉树
// 参数T是指向二叉树根的指针的指针
void Create_BiTree(BiTree *T)
{
    char ch;
    // 从标准输入读取一个字符
    ch = getchar();
    //当输入的是"#"时,认为该子树为空
    if(ch == '#')
        *T = NULL;// 将T指向的指针设为NULL,表示该子树为空
    //创建树结点
    else
    {
        // 动态分配内存空间给新的节点,并将地址赋值给T指向的指针
        *T = (BiTree)malloc(sizeof(struct TNode));
        // 设置新节点的数据
        (*T)->data = ch; //生成树结点
        // 递归地生成左子树
        Create_BiTree(&(*T)->lchild);
        // 递归地生成右子树
        Create_BiTree(&(*T)->rchild);
    }
}

// 先序遍历二叉树
void TraverseBiTree(BiTree T)
{
	// 如果节点为空,则直接返回
	if(T == NULL)
		return;
	else
	{
		// 访问节点
		printf("%c ",T->data);
		// 递归遍历左子树
		TraverseBiTree(T->lchild);
		// 递归遍历右子树
		TraverseBiTree(T->rchild);
	}
}

// 中序遍历二叉树
void InOrderBiTree(BiTree T)
{
	// 如果节点为空,则直接返回
	if(NULL == T)
		return;
	else
	{
		// 递归遍历左子树
		InOrderBiTree(T->lchild);
		// 访问节点
		printf("%c ",T->data);
		// 递归遍历右子树
		InOrderBiTree(T->rchild);
	}
}

// 后序遍历二叉树
void PostOrderBiTree(BiTree T)
{
	// 如果节点为空,则直接返回
	if(NULL == T)
		return;
	else
	{
		// 递归遍历左子树
		PostOrderBiTree(T->lchild);
		// 递归遍历右子树
		PostOrderBiTree(T->rchild);
		// 访问节点
		printf("%c ",T->data);
	}
}

// 计算二叉树的深度
int TreeDeep(BiTree T)
{
	int deep = 0; // 初始化深度为0
	if(T) // 如果树不为空
	{
		int leftdeep = TreeDeep(T->lchild); // 递归计算左子树的深度
		int rightdeep = TreeDeep(T->rchild); // 递归计算右子树的深度
		deep = leftdeep > rightdeep ? leftdeep + 1 : rightdeep + 1; // 取左右子树深度的最大值,并加1(因为根节点也算一层)
	}
	return deep; // 返回树的深度
}

// 统计二叉树的叶子节点数量,并打印叶子节点的值
void Leafcount(BiTree T, int *num)
{
	if(T) // 如果树不为空
	{
		if(T->lchild == NULL && T->rchild == NULL) // 如果当前节点是叶子节点(即左右子树都为空)
		{
			num++; // 叶子节点数量加1
			printf("%c ", T->data); // 打印叶子节点的值
		}
		Leafcount(T->lchild, num); // 递归遍历左子树
		Leafcount(T->rchild, num); // 递归遍历右子树
	}
}

// 二叉树的层序遍历(广度优先遍历)
void LevelOrder_BiTree(BiTree T)
{
    // 用一个队列保存结点信息,这里的队列采用的是顺序队列中的数组实现
    int front = 0; // 队列的前端指针
    int rear = 0;  // 队列的后端指针
    BiTree BiQueue[MAXSIZE]; // 假设MAXSIZE是队列的最大容量,这里是一个数组,用于模拟队列
    BiTree tempNode; // 临时节点,用于从队列中取出节点

    if(T != NULL) // 如果树不为空
    {
        BiQueue[rear++] = T; // 将根节点入队

        while(front != rear) // 当队列不为空时
        {
            // 取出队头元素,并使队头指针向后移动一位
            tempNode = BiQueue[front++];
            // 打印当前节点的值
            printf("%c ", tempNode->data);

            // 判断左子树是否为空,若不为空,则加入队列
            if(tempNode->lchild != NULL)
                BiQueue[rear++] = tempNode->lchild;

            // 判断右子树是否为空,若不为空,则加入队列
            if(tempNode->rchild != NULL)
                BiQueue[rear++] = tempNode->rchild;
        }
    }
}

int main(void)
{
	// 声明一个指向二叉树结构体的指针T,但这里T并没有直接分配内存
	BiTree T;

	int deepth, num = 0; // 声明树的深度和叶子节点数量的变量

	// 调用Create_BiTree函数,通过引用传递T的地址,创建二叉树,并将根节点地址赋值给T
	Create_BiTree(&T);

	// 输出先序遍历结果
	printf("先序遍历二叉树:\n");
	TraverseBiTree(T);
	printf("\n");

	// 输出中序遍历结果
	printf("中序遍历二叉树:\n");
	InOrderBiTree(T);
	printf("\n");

	// 输出后序遍历结果
	printf("后序遍历二叉树:\n");
	PostOrderBiTree(T);
	printf("\n");

	// 层次遍历二叉树,即广度优先遍历
	printf("层次遍历结果:");
	LevelOrder_BiTree(T);
	printf("\n");

	// 计算树的深度
	deepth = TreeDeep(T);
	printf("树的深度为:%d", deepth);
	printf("\n");

	// 计算并输出树的叶子节点
	printf("树的叶子结点为:");
	Leafcount(T,&num);

	printf("\n树的叶子结点个数为:%d", num);

	return 0;
}
图1-1 二叉树
图1-2 二叉树结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这道题目是关于如何利用二叉链表结构建立一棵二叉树并能实现二叉树先序遍历中序遍历后序遍历三种遍历算法,能够用队列实现二叉树层次遍历算法,并按层次输出标出),并能统计树叶结点高等。 ### 回答2: 二叉树是计算机科学中的一个重要概念,其本质上是一种树状结构,其中每个节点最多具有两个子节点。二叉树在计算机科学领域广泛应用,包括搜索树、表达式树、哈夫曼树等。下面我将就如何利用二叉链表结构建立一棵二叉树,并递归实现它的先序遍历中序遍历后序遍历三种遍历算法,用队列实现层次遍历算法,并按层次输出并能统计树叶、节点高等问题进行详细解答。 1.建立二叉树 建立二叉树可以通过二叉链表结构完成。所谓二叉链表结构,是指每个节点包含三个信息:节点值、左子节点和右子节点。以下是建立一棵二叉树程序框架: ``` class Node: def __init__(self, val=None, left=None, right=None): self.val = val self.left = left self.right = right class BinaryTree: def __init__(self, val=None): self.root = Node(val) def insert(self, val): if not self.root: self.root = Node(val) else: self._insert(val, self.root) def _insert(self, val, node): if val < node.val: if not node.left: node.left = Node(val) else: self._insert(val, node.left) else: if not node.right: node.right = Node(val) else: self._insert(val, node.right) ``` 2.递归实现遍历算法 接下来,我们可以使用递归实现二叉树先序遍历中序遍历后序遍历三种遍历算法。 (1)先序遍历,即先输出相应节点,再遍历左子树和右子树; ``` def preorder(self, node): if node: print(node.val) self.preorder(node.left) self.preorder(node.right) ``` (2)中序遍历,即先遍历左子树,再输出相应节点和右子树; ``` def inorder(self, node): if node: self.inorder(node.left) print(node.val) self.inorder(node.right) ``` (3)后序遍历,即先遍历左子树和右子树,再输出相应节点; ``` def postorder(self, node): if node: self.postorder(node.left) self.postorder(node.right) print(node.val) ``` 3.层次遍历算法 接下来,我们可以使用队列实现二叉树层次遍历算法,并按层次输出标出)。 ``` def levelorder(self): if not self.root: return [] queue = [self.root] res = [] level = 0 while queue: res.append([]) level_length = len(queue) for i in range(level_length): node = queue.pop(0) res[level].append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) level += 1 return res ``` 4.统计树叶、节点高等 最后,我们可以通过递归统计二叉树的叶、节点和深度。其中,深度可以使用递推的方式实现,具体代码如下: ``` def count_leaves(self, node): if not node: return 0 if not node.left and not node.right: return 1 else: return self.count_leaves(node.left) + self.count_leaves(node.right) def count_nodes(self, node): if not node: return 0 return 1 + self.count_nodes(node.left) + self.count_nodes(node.right) def depth(self, node): if not node: return 0 return 1 + max(self.depth(node.left), self.depth(node.right)) ``` 以上就是关于如何利用二叉链表结构建立二叉树,并递归实现遍历算法层次遍历算法,以及统计树叶、节点高等问题的详细解答。 ### 回答3: 二叉树特指每个节点最多只有两个子节点的树结构,节点的左右子节点顺序不同则构成不同的二叉树二叉链表结构利用指针来表示节点的数据结构,节点包含一个据域和两个指向左右子节点的指针。 建立二叉树的方式有多种,其中最基本的是先序遍历建立二叉树。即按照“根 - 左子树 - 右子树”的顺序从上至下递归遍历,并利用二叉链表结构生成树。先序遍历算法如下: 1. 若当前节点存在则输出该节点据; 2. 若当前节点的左孩子节点非空,则递归遍历左子树; 3. 若当前节点的右孩子节点非空,则递归遍历右子树。 中序遍历算法按照“左子树 - 根 - 右子树”的顺序遍历,并利用递归算法实现。 1. 若当前节点的左孩子节点非空,则递归遍历左子树; 2. 若当前节点存在则输出该节点据; 3. 若当前节点的右孩子节点非空,则递归遍历右子树。 后序遍历算法按照“左子树 - 右子树 - 根”的顺序遍历,并利用递归算法实现。 1. 若当前节点的左孩子节点非空,则递归遍历左子树; 2. 若当前节点的右孩子节点非空,则递归遍历右子树; 3. 若当前节点存在则输出该节点据。 层次遍历算法需要利用队列数据结构实现,具体算法如下: 1. 将根节点入队列; 2. 当队列非空时,弹出队头元素并输出该节点据; 3. 若该节点的左孩子节点非空,则将其入队列; 4. 若该节点的右孩子节点非空,则将其入队列; 5. 重复2至4步直到队列为空。 统计树叶、节点算法利用递归实现统计的代码实现如下: //统计树叶 int countLeaf(Tnode* root) { if (root == NULL) return 0; //空树则叶为0 else if (root->left == NULL && root->right == NULL) return 1; //只有一个节点则叶为1 else return countLeaf(root->left) + countLeaf(root->right); //递归计算左子树和右子树叶之和 } //统计节点 int countNode(Tnode* root) { if (root == NULL) return 0; //空树则节点为0 else return countNode(root->left) + countNode(root->right) + 1; //递归计算左子树和右子树节点之和加1 } //求高 int getHeight(Tnode* root) { if (root == NULL) return 0; //空树则高为0 else { int leftH = getHeight(root->left); //计算左子树的高 int rightH = getHeight(root->right); //计算右子树的高 return (leftH > rightH ? leftH : rightH) + 1; //返回左右子树高较大值加1 } } 因此,利用上述算法,我们可以通过建立一棵二叉链表结构二叉树实现递归实现二叉树先序遍历中序遍历后序遍历三种遍历算法,并利用队列实现二叉树层次遍历算法,并按层次输出标出),并可以统计树叶、节点高等

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值