用C语言写一个代码,完成以下四个功能:1. 任意输入前序+中序序列,生成唯一的二叉树,并打印其的后序序 列(当用户输入错误的序列无法生成二叉树时,程序应该有错误提示); 2. 判断输入的一棵二叉树是否是二叉搜索树; 3. 输入一棵二叉搜索树,求出其中的最小和最大关键字; 4. 将该二叉搜索树转换成一个排序的双向链表(要求不能创建任何新的结点,只能调整树 中结点指针的指向)。
时间: 2024-03-16 19:41:36 浏览: 70
C语言实现二叉树的各种操作。
4星 · 用户满意度95%
好的,以下是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树结构体
typedef struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
// 根据前序和中序遍历序列构建二叉树
TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) {
if (preorderSize == 0) {
return NULL;
}
// 创建根节点
TreeNode *root = (TreeNode*)malloc(sizeof(TreeNode));
root->val = preorder[0];
root->left = NULL;
root->right = NULL;
// 找到根节点在中序遍历序列中的位置
int rootIndex = 0;
while (inorder[rootIndex] != root->val) {
rootIndex++;
}
// 构建左子树
root->left = buildTree(preorder + 1, rootIndex, inorder, rootIndex);
// 构建右子树
root->right = buildTree(preorder + rootIndex + 1, preorderSize - rootIndex - 1, inorder + rootIndex + 1, inorderSize - rootIndex - 1);
return root;
}
// 打印二叉树后序遍历序列
void postorderTraversal(TreeNode* root) {
if (root == NULL) {
return;
}
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ", root->val);
}
// 判断一棵二叉树是否是二叉搜索树
int isValidBST(TreeNode* root) {
return isValidBSTWithMinMax(root, NULL, NULL);
}
int isValidBSTWithMinMax(TreeNode* root, TreeNode* minNode, TreeNode* maxNode) {
if (root == NULL) {
return 1;
}
if (minNode && root->val <= minNode->val) {
return 0;
}
if (maxNode && root->val >= maxNode->val) {
return 0;
}
return isValidBSTWithMinMax(root->left, minNode, root) && isValidBSTWithMinMax(root->right, root, maxNode);
}
// 求二叉搜索树中的最小和最大关键字
void findMinMax(TreeNode* root, int* min, int* max) {
if (root == NULL) {
return;
}
if (root->val < *min) {
*min = root->val;
}
if (root->val > *max) {
*max = root->val;
}
findMinMax(root->left, min, max);
findMinMax(root->right, min, max);
}
// 将二叉搜索树转换为排序的双向链表
TreeNode* convertBSTToDoublyLinkedList(TreeNode* root) {
if (root == NULL) {
return NULL;
}
// 将左子树转换为链表
TreeNode* leftList = convertBSTToDoublyLinkedList(root->left);
// 找到左子树链表的最后一个节点
TreeNode* leftLast = leftList;
while (leftLast && leftLast->right) {
leftLast = leftLast->right;
}
// 将根节点插入到左子树链表的末尾
if (leftLast) {
leftLast->right = root;
root->left = leftLast;
}
// 将右子树转换为链表
TreeNode* rightList = convertBSTToDoublyLinkedList(root->right);
// 将右子树链表插入到根节点之后
if (rightList) {
rightList->left = root;
root->right = rightList;
}
// 返回整个链表的头节点
return leftList ? leftList : root;
}
int main() {
int preorder[] = {3, 9, 20, 15, 7};
int inorder[] = {9, 3, 15, 20, 7};
int n = sizeof(preorder) / sizeof(preorder[0]);
// 构建二叉树
TreeNode* root = buildTree(preorder, n, inorder, n);
if (root == NULL) {
printf("输入的序列无法生成二叉树!\n");
return 0;
}
// 打印二叉树后序遍历序列
printf("二叉树后序遍历序列为:");
postorderTraversal(root);
printf("\n");
// 判断是否是二叉搜索树
if (isValidBST(root)) {
printf("该二叉树是一棵二叉搜索树!\n");
// 求最小和最大关键字
int min = root->val;
int max = root->val;
findMinMax(root, &min, &max);
printf("最小关键字为:%d,最大关键字为:%d\n", min, max);
// 将二叉搜索树转换成排序的双向链表
TreeNode* head = convertBSTToDoublyLinkedList(root);
printf("双向链表从小到大的顺序为:");
while (head) {
printf("%d ", head->val);
head = head->right;
}
printf("\n");
} else {
printf("该二叉树不是一棵二叉搜索树!\n");
}
return 0;
}
```
其中,我们在构建二叉树时,参考了前序遍历和中序遍历的特点,将序列划分为左子树和右子树,并递归构建子树。在判断二叉树是否是二叉搜索树时,我们采用了递归的方法,每次传入一个区间的最小值和最大值,判断当前节点是否在区间内。在将二叉搜索树转换为排序的双向链表时,我们采用了递归的方法,先将左子树转换为链表,再将右子树转换为链表,并将左子树链表和右子树链表插入到根节点之前和之后。
阅读全文