设二叉树以二叉链表形式存放,用类C语言设计非递归算法判断一棵根结点为T的二叉树是否为二叉排序树。要求不使用已有的算法和栈,并配有详细注释
时间: 2023-06-12 18:04:57 浏览: 96
以下是使用类C语言设计的非递归算法判断一棵根结点为T的二叉树是否为二叉排序树的代码:
```c
// 定义二叉树结点结构体
typedef struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
// 判断一棵二叉树是否为二叉排序树
int isBST(TreeNode* root) {
// 如果根结点为空,则是二叉排序树
if (root == NULL) {
return 1;
}
// 定义一个指针pre,用于记录中序遍历中的前驱结点
TreeNode* pre = NULL;
// 定义一个指针p,用于遍历二叉树
TreeNode* p = root;
// 定义一个变量flag,用于记录二叉树是否为二叉排序树
int flag = 1;
while (p != NULL) {
// 如果当前结点有左子树,则找到左子树中的最右结点
if (p->left != NULL) {
TreeNode* q = p->left;
while (q->right != NULL && q->right != p) {
q = q->right;
}
// 如果最右结点的右指针为空,则将其指向当前结点,然后继续遍历左子树
if (q->right == NULL) {
q->right = p;
p = p->left;
}
// 如果最右结点的右指针指向当前结点,则说明左子树已经遍历完成,可以进行中序遍历
else {
// 如果当前结点的值小于等于前驱结点的值,则二叉树不是二叉排序树
if (pre != NULL && pre->val >= p->val) {
flag = 0;
}
pre = p;
q->right = NULL;
p = p->right;
}
}
// 如果当前结点没有左子树,则直接进行中序遍历
else {
// 如果当前结点的值小于等于前驱结点的值,则二叉树不是二叉排序树
if (pre != NULL && pre->val >= p->val) {
flag = 0;
}
pre = p;
p = p->right;
}
}
return flag;
}
```
注释如下:
1. `isBST` 函数的作用是判断一棵二叉树是否为二叉排序树,其参数为二叉树的根结点指针。
2. 如果根结点为空,则是二叉排序树,直接返回 1。
3. 定义指针 `pre`,用于记录中序遍历中的前驱结点;定义指针 `p`,用于遍历二叉树;定义变量 `flag`,用于记录二叉树是否为二叉排序树,初始化为 1。
4. 进入 while 循环,如果当前结点有左子树,则找到左子树中的最右结点,用于建立线索。
5. 如果最右结点的右指针为空,则将其指向当前结点,然后继续遍历左子树。
6. 如果最右结点的右指针指向当前结点,则说明左子树已经遍历完成,可以进行中序遍历。
7. 如果当前结点的值小于等于前驱结点的值,则二叉树不是二叉排序树,将 `flag` 置为 0。
8. 更新前驱结点为当前结点,然后断开线索,遍历右子树。
9. 如果当前结点没有左子树,则直接进行中序遍历。
10. 如果当前结点的值小于等于前驱结点的值,则二叉树不是二叉排序树,将 `flag` 置为 0。
11. 更新前驱结点为当前结点,然后遍历右子树。
12. 循环结束后,返回 `flag` 的值,即二叉树是否为二叉排序树的判断结果。
阅读全文