判断二叉树代码+报告

该文详细介绍了如何构建二叉树、输出其先序、中序、后序遍历序列以及判断是否为二叉排序树的方法。通过二叉链表存储二叉树,利用递归遍历并检查节点关键字关系来确定是否满足二叉排序树的性质。代码示例中,使用C语言实现了这些功能,并在最后给出了执行结果和个人总结。
摘要由CSDN通过智能技术生成

判断二叉排序树
一、小组信息

学号姓名

二、题目以及功能实现:
题目8:判断一棵树是否为一棵二叉排序树。
实验内容如下:
(1)构建一棵二叉树
(2)输出二叉树的先序、中序、后序遍历序列
(3)判断是否为一棵二叉排序树
三、题目分析:

  1. 构建一棵二叉树
    二叉树主要有顺序存储结构和链式存储结构两种存储方式,因顺序存储主要应用于完全二叉树和满二叉树,否则容易造成大量存储空间的浪费。因此,本题中适用于一般的二叉树,采用二叉链表构建二叉树。
  2. 输出二叉树的的先序、中序、后序遍历序列
    利用二叉树的递归定义,二叉树的遍历只需依次遍历二叉树的根节点、左子树和右子树三个基本部分。根据访问顺序的不同可以得到DLR(先序遍历),LDR(中序遍历),LRD(后序遍历)。
  3. 判断一棵树是否为一棵二叉排序树
    根据二叉排序树(BST)的定义知,二叉排序树或为空二叉树,或为具有以下性质的二叉树:
    (1) 左子树上的所有结点的关键字均小于根节点的关键字;
    (2) 右子树上的所有结点的关键字均大于根节点的关键字;
    (3) 左子树和右子树又各是一棵二叉排序树。
    因此,我们有几种思路,由(1)知,对二叉树进行递归遍历,左子树关键字比根结点关键字小,右子树的关键字比根结点的关键字大,一旦有不满足条件则可判断不是二叉排序树;由(1)(2)知,左子树结点值<根结点值<右子树结点值,其中序遍历序列是一个递增序列,因此,对给定的二叉树进行中序遍历,如果始终能保持前一个值比后一个值小,则说明该二叉树是一棵二叉排序树,反之则不然。
    四、数据结构定义:
    在这里插入图片描述

五、关键部分程序实现(主要函数)
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define maxsize 1024

 int predt = -32756;
 
typedef int datatype;
 //二叉链表结点定义 
typedef struct node{
	datatype data;
	struct node *lchild,*rchild;
}bitree;


//二叉树的建立
bitree *CreatTree(){
	int num;
	bitree *Q[maxsize];//设置指针类型构成队列 
	int front,rear;
	bitree *root,*s;
	root = NULL;//二叉树置空
	front = 1;
	rear = 0; 
	scanf("%d",&num);
	while(num!=-1){
		s = NULL;
		if(num!=0){
			s = (bitree*)malloc(sizeof(bitree));
			s->data = num;
			s->lchild = NULL;
			s->rchild = NULL;
		}
		rear++;
		Q[rear] = s;
		
		if(rear == 1){
			root = s;
		}else {
			if(s&&Q[front]){
				if(rear%2==0){
					Q[front]->lchild = s;
				}else {
					Q[front]->rchild = s;
				}
				if(rear%2 == 1){
					front++;
				}
			}
		}
		scanf("%d",&num);
	}
	return root;
} 

//DLR
void preorder(bitree*p){
	if(p!=NULL){
		printf("%d ",p->data);
		preorder(p->lchild);
		preorder(p->rchild);
	}
}

//LDR
void inorder(bitree*p){
	if(p!=NULL){
		inorder(p->lchild);
		printf("%d ",p->data);
		inorder(p->rchild);
	}
}

//LRD
void posorder(bitree*p){
	if(p!=NULL){
		posorder(p->lchild);
		posorder(p->rchild);
		printf("%d ",p->data);
	}
}


//判断是否为二叉排序树 
int isBST(bitree*p){
		int b1,b2;
		if(p == NULL) return 1;//空树
		else{
			b1 = isBST(p->lchild);
			if(b1 == 0||predt > p->data) return 0;
			predt = p->data;
			b2 = isBST(p->rchild);
			return b2; 
		} 
}

//主函数 
int main(){
	printf("请输入数据:"); 
	bitree *root = CreatTree();
	printf("先序:");
	preorder(root);
	printf("\n");
	printf("中序:");
	inorder(root);
		printf("\n");
	printf("后序:"); 
	posorder(root);
		printf("\n");
		if(isBST(root)){
			printf("该树是一棵二叉排序树"); 
		}else printf("该树不是一棵二叉排序树");
}

六、执行结果:
练习例程一:
在这里插入图片描述

练习例程二:
在这里插入图片描述

七、个人总结:
姓名:
通过本次大作业一练习,成功实现了题目的要求,但仍有很多不足之处。在二叉排序树的数据存储中并没有使用字符类型,为了方便起见使用了整型,用数字0代替原本的零输入’@’,数字-1代替原本的结束符号“#”。因此,忽略了属于数据有0和-1的情形。在大作业交了之后,会花些时间继续改善代码使其更具有普适性。

判断一棵二叉树是否为完全二叉树,我们需要检查以下条件: 1. 完全二叉树的每个层级都是满的,除了最后一个层级可能不满,但所有节点都尽可能地靠左排列。 2. 如果存在最后一层,则最后一层的所有节点都在左边。 这里有一个简单的C++代码实现,使用深度优先搜索(DFS)遍历二叉树并记录节点的数量,同时跟踪当前层级: ```cpp #include <iostream> using namespace std; // 定义二叉树节点 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; // 判断是否为完全二叉树 bool isCompleteBinaryTree(TreeNode* root) { if (root == nullptr) return true; // 空树视为完全二叉树 int level = 0, count = 1, node = root; while (node != nullptr) { ++level; if (node->left != nullptr && node->right != nullptr) { // 如果左右子节点都存在,更新计数器 count += 2; } else { // 否则,只增加1 count++; } node = node->left ? node->right : node->left ? node->left : nullptr; // 跟踪下一个节点 } // 遍历结束后,检查是否存在不满足完整性的节点 for (int i = 1; i < level; ++i) { if (count % 2 == 1) { // 偶数层级表示满,奇数层级可能存在未填充节点 if ((count - 1) / 2 < pow(2, i)) { // 不满足完全二叉树条件 return false; } } else { if (count < pow(2, i + 1)) { // 最后一层,检查所有节点是否都在左侧 return false; } } count /= 2; } return true; } int main() { // 测试用例 TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); root->left->left = new TreeNode(4); root->left->right = new TreeNode(5); cout << (isCompleteBinaryTree(root) ? "是" : "否") << endl; // 输出:是 // ... 更多测试用例... return 0; } ``` 这个代码首先检查根节点,然后递归遍历二叉树。对于每一层,如果左右都有节点,则数量翻倍;否则,数量加一。遍历完成后,根据规则检查每层节点数量是否满足完全二叉树的定义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值