二叉树以顺序储存的方式存放,检测该二叉树是否为二叉搜索树

  1. 二叉搜索树也称为二叉排序树,就是任意结点值大于左子树的全部结点值,且小于右子树的全部结点值
  2. 若以顺序存储的方式存放,下标之间是有关系的,
    在这里插入图片描述
  3. 因为是要检测是否为二叉排序树,所以要查看所有的子树的根是否大于左子树的所有结点的值以及小于右子树所有结点的值,可以想到从叶子结点开始向上检测。
typedef struct TTT{
	int SqBiTNode[MAXSIZE];
	int num;
}SqBiTree;
bool isBST(SqBiTree bt) 
{
	// 因为是顺序存储的,也就是在数组中进行存储,下标之间有关系,
	// 分别进行左右子树的维护,从最后一层开始,二叉搜索树为左边的树比右边的树小(二叉排序树),
	// 每一个结点都有左右子树,所以要分别维护当前结点整个子树的最大最小值
	// 1) 当 当前结点为父结点的左孩子时,父节点要大于 以当前结点的整棵树的最大值
	// 2) 当 当前结点为父结点的右孩子时,父结点要小于 以当前结点的整棵树的最小值
	// 所以要维护以每个结点的整棵树的最大最小值 
	int *pmin,*pmax;
	pmin =  (int*)malloc(sizeof(int)*(bt.num));
	pmax =  (int*)malloc(sizeof(int)*(bt.num));
	
	// 初始化的最大最小等于自身 
	for(int i=0;i<bt.num;i++){
		pmin[i] = pmax[i] = bt.SqBiTNode[i];
	}
	// 从叶子结点往上遍历 
	for(int i=bt.num-1;i>0;i--){
		// 该结点不为空 
		if(bt.SqBiTNode[i] != -1){
			int m = (i-1)/2;          // 获取父结点的下标 
			if(i&1 && bt.SqBiTNode[m]>pmax[i]){  // 若当前结点为左孩子,且父结点比左孩子大,父结点的最大值还等于自身,最小值要维护成左子树的最小值 
				pmin[m] = pmin[i];
			}else if (!(i&1) && bt.SqBiTNode[m]<pmin[i]){  // 若当前结点为右孩子,且父结点比右孩子小,父结点的最小值还等于自身,最大值要维护成右子树的最大值 
				pmax[m] = pmax[i];
			}else {                             // 其他情况:父结点比左子树小或父结点比右子树大,结束 
				return false;
			} 
				
		}
	}
	return true;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 假设非空二叉树采用顺序存储结构,每个节点为单个字符。要求设计一个算法求编号为i的节点的层次。 首先,我们需要了解一下二叉树顺序存储结构。在顺序存储结构中,二叉树的节点按照层次顺序依次存储在一个一维数组中,根节点存储在数组下标为1的位置,左子节点存储在数组下标为2i的位置,右子节点存储在数组下标为2i+1的位置(i为节点在数组中的下标)。 因此,我们可以通过以下步骤求编号为i的节点的层次: 1. 如果i等于1,则该节点为根节点,层次为1。 2. 如果i不等于1,则可以通过以下公式计算该节点的父节点在数组中的下标:i/2(向下取整)。然后,递归地求出该父节点的层次,再加1即为该节点的层次。 下面是该算法的伪代码实现: function getLevel(i): if i == 1: return 1 else: parent = i / 2 return getLevel(parent) + 1 其中,/表示整除运算,即向下取整。 ### 回答2: 假设非空二叉树采用顺序存储结构,节点编号从1开始,每个节点为单个字符。要求设计一个算法求编号为i的节点的层次。 首先,我们需要知道二叉树的层次遍历顺序。层次遍历是按照从上到下、从左到右的顺序遍历二叉树的所有节点。具体的实现可以使用队列数据结构。我们从根节点开始,将根节点加入队列中。之后,在while循环中,每次取出队列的首节点,将其左右孩子节点(如果存在)加入队列中。这样就可以按照层次遍历的顺序遍历二叉树。 现在,我们要设计一个算法求编号为i的节点的层次。思路如下: 1. 初始化层次level为1,节点位置pos为1。 2. 进入while循环,循环条件为pos小于等于i。 3. 在循环中,判断pos与i是否相等,如果相等,则找到了目标节点,返回当前层次level。 4. 如果pos小于i,说明我们还没找到目标节点,继续遍历下一个节点。将当前节点的左右孩子加入队列,并依次更新层次level和节点位置pos。 5. 如果pos大于i,说明节点编号i不存在,可以在循环外直接返回一个错误状态。 按照上述思路,我们可以设计出如下的C++代码: ```cpp #include <iostream> #include <queue> using namespace std; struct TreeNode { char data; TreeNode* left; TreeNode* right; }; int getLevel(TreeNode* root, int i) { if (root == nullptr || i <= 0) { return -1; // 错误状态 } queue<TreeNode*> q; q.push(root); int level = 1; int pos = 1; while (!q.empty() && pos <= i) { int size = q.size(); while (size--) { TreeNode* node = q.front(); q.pop(); if (pos == i) { return level; } if (node->left) { q.push(node->left); pos++; } if (node->right) { q.push(node->right); pos++; } } level++; } return -1; // 错误状态 } int main() { // 构建一个二叉树进行测试 TreeNode* root = new TreeNode{'A', nullptr, nullptr}; root->left = new TreeNode{'B', nullptr, nullptr}; root->right = new TreeNode{'C', nullptr, nullptr}; root->left->left = new TreeNode{'D', nullptr, nullptr}; root->left->right = new TreeNode{'E', nullptr, nullptr}; root->right->left = new TreeNode{'F', nullptr, nullptr}; root->right->right = new TreeNode{'G', nullptr, nullptr}; int i; cout << "请输入要查询的节点编号i:"; cin >> i; int level = getLevel(root, i); if (level != -1) { cout << "节点编号为" << i << "的节点属于第" << level << "层" << endl; } else { cout << "节点编号为" << i << "的节点不存在" << endl; } return 0; } ``` 以上的代码中,我们假设构建了一个如下的二叉树进行测试: ```plaintext A / \ B C / \ / \ D E F G ``` 运行示例: ``` 请输入要查询的节点编号i:6 节点编号为6的节点属于第2层 ``` ``` 请输入要查询的节点编号i:8 节点编号为8的节点不存在 ``` 通过以上算法和代码,我们就可以求得编号为i的节点的层次了。 ### 回答3: 采用顺序存储结构的非空二叉树,可以使用数组来存储节点。这种存储结构的特点是,二叉树的根节点存储在数组的第一个位置,而任意一个编号为i的节点的左孩子存储在数组的2i位置,右孩子存储在数组的2i+1位置。 要求编号为i的节点的层次,可以按照以下步骤设计算法: 1. 定义一个变量level,并将其初始设为1,表示根节点的层次为1。 2. 如果i等于1,则返回level即可。 3. 否则,对于任意一个编号为i的节点,其父节点的编号可以通过 i/2 计算得到。我们可以在循环中持续计算当前节点的父节点,直到父节点的编号等于1。 4. 在每次循环中,将level加1,表示当前节点的层次比其父节点多1。 5. 循环结束后,返回level,即为编号为i的节点的层次。 下面是该算法的代码示例: ```python def get_level_of_node(i): level = 1 if i == 1: return level else: while i != 1: i = i // 2 level += 1 return level ``` 需要注意的是,上述算法中假设了给定非空二叉树采用顺序存储结构,即每个节点的编号和在数组中的位置是一一对应的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值