分别对原有序列和需要检查的序列建立一棵二叉搜索树,然后分别进行前序遍历得到字符串结果,如果字符串结果相同,输出“Yes”,否则“No”。
#include <iostream>
using namespace std;
const int N = 20;
typedef struct TreeNode *Tree;
struct TreeNode
{
int data;
Tree left, right;
};
int n, l;
Tree insert(Tree T, int x)
{
if (!T)
{
T = (Tree)malloc(sizeof(struct TreeNode));
T->data = x;
T->left = T->right = NULL;
}
else
{
if (x < T->data) T->left = insert(T->left, x);
else if (x > T->data) T->right = insert(T->right, x);
}
return T;
}
Tree buildTree(int n)
{
int x;
Tree T = NULL;
for (int i = 0; i < n; i ++)
{
cin >> x;
T = insert(T, x);
}
return T;
}
void preTravel(Tree T, string &s)
{
if (T)
{
s += T->data + '0';
preTravel(T->left, s);
preTravel(T->right, s);
}
}
int main()
{
while (cin >> n, n)
{
cin >> l;
Tree T1 = buildTree(n);
string s1 = "";
preTravel(T1, s1);
for (int i = 0; i < l; i ++)
{
Tree T2 = buildTree(n);
string s2 = "";
preTravel(T2, s2);
if (s1 == s2) puts("Yes");
else puts("No");
}
}
return 0;
}
原理参考这里
#include <iostream>
using namespace std;
typedef struct AVLNode *AVLTree;
struct AVLNode
{
int data; // 值
AVLTree left, right; // 左右子树
int height; // 树高
};
// 树高,空树为-1
int get_height(AVLTree A)
{
return A == NULL ? -1 : A->height;
}
// LL单旋
// 把 B 的右子树腾出来挂给 A 的左子树,再将 A 挂到 B 的右子树上去
AVLTree LLRotation(AVLTree A)
{
AVLTree B = A->left;
A->left = B->right;
B->right = A;
A->height = max(get_height(A->left), get_height(A->right)) + 1;
B->height = max(get_height(B->left), get_height(B->right)) + 1;
return B;
}
// RR单旋
// 把 B 的左子树腾出来挂到 A 的右子树上,再将 A 挂在 B 的左子树上
AVLTree RRRotation(AVLTree A)
{
AVLTree B = A->right;
A->right = B->left;
B->left = A;
A->height = max(get_height(A->left), get_height(A->right)) + 1;
B->height = max(get_height(B->left), get_height(B->right)) + 1;
return B;
}
// LR 双旋
AVLTree LRRotation(AVLTree A)
{
// 先 RR 单旋
A->left = RRRotation(A->left);
// 再 LL 单旋
return LLRotation(A);
}
// RL双旋
AVLTree RLRotation(AVLTree A)
{
// 先 LL 单旋
A->right = LLRotation(A->right);
// 再 RR 单旋
return RRRotation(A);
}
AVLTree Insert(AVLTree T, int x)
{
if (!T)
{
T = (AVLTree)malloc(sizeof (struct AVLNode));
T->data = x;
T->left = T->right = NULL;
T->height = 0;
}
else
{
// 左子树
if (x < T->data)
{
T->left = Insert(T->left, x);
if (get_height(T->left) - get_height(T->right) == 2)
{
// 左子树的左子树,LL单旋
if (x < T->left->data) T = LLRotation(T);
// 左子树的右子树,LR单旋
else if (x > T->left->data) T = LRRotation(T);
}
}
// 右子树
else if (x > T->data)
{
T->right = Insert(T->right, x);
if (get_height(T->right) - get_height(T->left) == 2)
{
// 右子树的右子树,RR单旋
if (x > T->right->data) T = RRRotation(T);
// 右子树的左子树,RL单旋
else if (x < T->right->data) T = RLRotation(T);
}
}
}
T->height = max(get_height(T->left), get_height(T->right)) + 1;
return T;
}
int main()
{
AVLTree T = NULL;
int n, x;
cin >> n;
for (int i = 0; i < n; i ++)
{
cin >> x;
T = Insert(T, x);
}
cout << T->data;
return 0;
}
插入、删除、找 X、找最小、找最大。
BinTree Insert( BinTree BST, ElementType X )
{
if (!BST)
{
BST = (BinTree)malloc(sizeof (struct TNode));
BST->Data = X;
BST->Left = BST->Right = NULL;
}
else
{
if (X < BST->Data) BST->Left = Insert(BST->Left, X);
else if (X > BST->Data) BST->Right = Insert(BST->Right, X);
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X )
{
if (!BST) puts("Not Found");
else if (X < BST->Data) BST->Left = Delete(BST->Left, X);
else if (X > BST->Data) BST->Right = Delete(BST->Right, X);
else
{
if (BST->Left && BST->Right)
{
BinTree tmp = FindMin(BST->Right);
BST->Data = tmp->Data;
Delete(BST->Right, tmp->Data);
}
else
{
BinTree tmp = BST;
if (!BST->Left) BST = BST->Right;
else if (!BST->Right) BST = BST->Left;
free(tmp);
}
}
return BST;
}
Position Find( BinTree BST, ElementType X )
{
if (!BST) return NULL;
if (X < BST->Data) return Find(BST->Left, X);
else if (X > BST->Data) return Find(BST->Right, X);
else return BST;
}
Position FindMin( BinTree BST )
{
if (!BST) return NULL;
else if (!BST->Left) return BST;
else return FindMin(BST->Left);
}
Position FindMax( BinTree BST )
{
if (!BST) return NULL;
else if (!BST->Right) return BST;
else return FindMax(BST->Right);
}
树6 Complete Binary Search Tree
对输入节点进行升序排列后,就是对该树的中序遍历,创建一个新数组 res
,递归搜索左右子树的根节点,依次放到 res
中,就可以得到层次遍历。
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 2010;
int a[N], res[N];
// 求树的层数,从1开始
int get_level(int n)
{
int cur = 1;
while (pow(2, cur) - 1 < n) cur ++;
return cur;
}
// 计算 n 个结点的树其左树结点个数
int getLeftTreeSize(int n)
{
// 层数
int level = get_level(n);
// 最后一层节点个数
int last = n + 1 - pow(2, level - 1);
last = last < pow(2, level - 2) ? last : pow(2, level - 2);
// 左子树节点个数
int L = pow(2, level - 2) - 1 + last;
return L;
}
void fill(int left, int right, int root)
{
int n = right - left + 1;
if (!n) return;
int L = getLeftTreeSize(n); // 计算root节点的左子树节点个数
res[root] = a[left + L]; // root节点的值
int leftroot = root * 2 + 1; // 左子树的根节点
int rightroot = leftroot + 1; // 右子树的根节点
fill(left, left + L - 1, leftroot);
fill(left + L + 1, right, rightroot);
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
sort(a, a + n);
fill(0, n - 1, 0);
for (int i = 0; i < n - 1; i ++) cout << res[i] << " ";
cout << res[n - 1];
return 0;
}