PTA浙江大学数据结构习题——第四周

树4 是否同一棵二叉搜索树

分别对原有序列和需要检查的序列建立一棵二叉搜索树,然后分别进行前序遍历得到字符串结果,如果字符串结果相同,输出“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;
}

树5 Root of AVL Tree

原理参考这里

#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;
}

树7 二叉搜索树的操作集

插入、删除、找 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;
}

猜你喜欢

转载自blog.csdn.net/ManiacLook/article/details/124286050