1043 Is It a Binary Search Tree (25分)

16 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述

思路

题目给出一个先序序列,分析如下:

  • 根据BST的性质,对于一个结点,它的左子树的所有结点的值小于该结点的值,它的右子树的所有结点的值小于等于该结点的值。
  • 对于先序序列,第一个是根的值,之后是根的左子树的值的序列,最后是根的右子树的值的序列,如下图所示:
    在这里插入图片描述
    只要找出左右子树的分界,就可以递归地根据先序序列构造后序序列。可以分别从序列左侧和序列右侧开始向中间扫描,最后确定左右子树的分界线。如果得到的分界线不符合要求,直接让序列构造函数返回,于是构造后序序列成功的标志是:得到的后序序列的长度为n
  • 如果判断给出的先序序列不是BST,则将左右子树划分规则反转,再次构造后序序列,如果构造成功,则为镜像BST。
代码
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> preorder;
vector<int> postorder;
int n;
bool isMirror = false;
void findPostOrder(int root, int tail) {
	if (root > tail) 
		return;
	int i = root + 1, j = tail;
	if (!isMirror) {
		while (i <= tail && preorder[i] < preorder[root])
			i++;
		while (j > root && preorder[j] >= preorder[root])
			j--;
	}
	else {
		while (i <= tail && preorder[i] > preorder[root])
			i++;
		while (j > root && preorder[j] <= preorder[root])
			j--;
	}
	if (i - j != 1)
		return;
	findPostOrder(root + 1, j);
	findPostOrder(i, tail);
	postorder.push_back(preorder[root]);
}
int main() {
	scanf("%d", &n);
	preorder.resize(n);
	for (int i = 0;i < n;i++) {
		scanf("%d", &preorder[i]);
	}
	findPostOrder(0, n - 1);
	if (postorder.size() != n) {
		postorder.clear();
		isMirror = true;
		findPostOrder(0, n - 1);
	}
	if (postorder.size() == n) {
		printf("YES\n");
		for (int i = 0;i < postorder.size();i++) {
			if (i != 0) {
				printf(" ");
			}
			printf("%d", postorder[i]);
		}
	}
	else {
		printf("NO\n");
	}
}

另解:根据给出的先序序列构造BST,接着用构造的BST的先序序列给出的先序序列进行对比,如果两者相同说明给出的先序序列是BST。

#include<iostream>
#include<vector>
using namespace std;
struct node {
	int val;
	node *left, *right;
	node(int v) {
		val = v;
		left = NULL;
		right = NULL;
	}
}*root = NULL;
void insert(node *&cur, int val) {
	if (cur == NULL) {
		cur = new node(val);
		return;
	}
	if (cur->val > val) 
		insert(cur->left, val);
	else insert(cur->right, val);
}
vector<int> pre;
void preorderTraverse(node *cur) {
	if (cur == NULL)
		return;
	pre.push_back(cur->val);
	preorderTraverse(cur->left);
	preorderTraverse(cur->right);
}
void exchange(node *cur) {
	if (cur == NULL)
		return;
	swap(cur->left, cur->right);
	exchange(cur->left);
	exchange(cur->right);
}
vector<int> res;
void postorderTraverse(node *cur) {
	if (cur == NULL)
		return;
	postorderTraverse(cur->left);
	postorderTraverse(cur->right);
	res.push_back(cur->val);
}
int main() {
	vector<int> preorder;
	int n;
	cin >> n;
	preorder.resize(n);
	for (int i = 0;i < n;i++) {
		cin >> preorder[i];
		insert(root, preorder[i]);
	}
	preorderTraverse(root);
	bool isBST = true;
	for (int i = 0;i < n;i++) {
		if (preorder[i] != pre[i]) {
			isBST = false;
			break;
		}
	}
	if (!isBST) {
		exchange(root);
		pre.clear();
		preorderTraverse(root);
		isBST = true;
		for (int i = 0;i < n;i++) {
			if (preorder[i] != pre[i]) {
				isBST = false;
				break;
			}
		}
	}
	if (isBST) {
		cout << "YES" << endl;
		postorderTraverse(root);
		for (int i = 0;i < res.size();i++) {
			if (i != 0)
				cout << " ";
			cout << res[i];
		}
	}
	else {
		cout << "NO";
	}
}
【Solution】 To convert a binary search tree into a sorted circular doubly linked list, we can use the following steps: 1. Inorder traversal of the binary search tree to get the elements in sorted order. 2. Create a doubly linked list and add the elements from the inorder traversal to it. 3. Make the list circular by connecting the head and tail nodes. 4. Return the head node of the circular doubly linked list. Here's the Python code for the solution: ``` class Node: def __init__(self, val): self.val = val self.prev = None self.next = None def tree_to_doubly_list(root): if not root: return None stack = [] cur = root head = None prev = None while cur or stack: while cur: stack.append(cur) cur = cur.left cur = stack.pop() if not head: head = cur if prev: prev.right = cur cur.left = prev prev = cur cur = cur.right head.left = prev prev.right = head return head ``` To verify the accuracy of the code, we can use the following test cases: ``` # Test case 1 # Input: [4,2,5,1,3] # Output: # Binary search tree: # 4 # / \ # 2 5 # / \ # 1 3 # Doubly linked list: 1 <-> 2 <-> 3 <-> 4 <-> 5 # Doubly linked list in reverse order: 5 <-> 4 <-> 3 <-> 2 <-> 1 root = Node(4) root.left = Node(2) root.right = Node(5) root.left.left = Node(1) root.left.right = Node(3) head = tree_to_doubly_list(root) print("Binary search tree:") print_tree(root) print("Doubly linked list:") print_list(head) print("Doubly linked list in reverse order:") print_list_reverse(head) # Test case 2 # Input: [2,1,3] # Output: # Binary search tree: # 2 # / \ # 1 3 # Doubly linked list: 1 <-> 2 <-> 3 # Doubly linked list in reverse order: 3 <-> 2 <-> 1 root = Node(2) root.left = Node(1) root.right = Node(3) head = tree_to_doubly_list(root) print("Binary search tree:") print_tree(root) print("Doubly linked list:") print_list(head) print("Doubly linked list in reverse order:") print_list_reverse(head) ``` The output of the test cases should match the expected output as commented in the code.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值