BST的例题

例题一、查找任意BST树的第K小的结点。
Solution 1:
思想是采用中序遍历
int SupkthSmallest(struct TreeNode* root, int k,int *count,bool *flag)
{
        int result = 0;
        if(!root)
            return result;
        result =  SupkthSmallest(root->left, k,count,flag);
        (*count)++;
        if((*count) == k)
        {
            *flag = true;
            return root->val;
        }
        if(!(*flag))
        {
            result =  SupkthSmallest(root->right, k,count,flag); 
        }    
        return result;
}

int kthSmallest(struct TreeNode* root, int k) {
    int count = 0;
    bool flag = false;
    return SupkthSmallest(root, k, &count,&flag);   
}
例题二、

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.

每个节点变成本身加上比它大的所有值。

Solution 1:遍历每个值刷新即可
int getSum(struct TreeNode *root,struct TreeNode *self)
{
    if(!root)
        return 0;
    if(root->val < self->val)
        return (getSum(root->left,self)+getSum(root->right,self));
    else
        return (root->val+getSum(root->left,self)+getSum(root->right,self));
}

void Recursion(struct TreeNode *root,struct TreeNode *NowNode,struct TreeNode ** CopyRoot)
{
    if(!NowNode)
    {
        (*CopyRoot) = NULL;
        return;
    }
    (*CopyRoot) = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    (*CopyRoot)->val = getSum(root,NowNode);
    Recursion(root,NowNode->left,&((*CopyRoot)->left));
    Recursion(root,NowNode->right,&((*CopyRoot)->right));
}

struct TreeNode* convertBST(struct TreeNode * root) {
    struct TreeNode * CopyRoot;
    Recursion(root,root,&CopyRoot);
    return CopyRoot;
}

速度非常的慢。

-------------------------------------------------
Solution 2:
利用BST树的特性对递归进行了改进:
int GetSum(struct TreeNode *root,struct TreeNode *NowNode)
{
    if(!root)
        return 0;
    if(root->val > NowNode->val)
        return (root->val+GetSum(root->left,NowNode)+GetSum(root->right,NowNode));
    else if(root->val < NowNode->val)
        return(GetSum(root->right,NowNode));
    else
        return(root->val+GetSum(root->right,NowNode));
}

void SupconvertBST(struct TreeNode * root,struct TreeNode * NowNode,struct TreeNode ** NewRoot)
{
    (*NewRoot) = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    (*NewRoot)->val = GetSum(root,NowNode);
    (*NewRoot)->left = (*NewRoot)->right = NULL;
    if(NowNode->left)
      SupconvertBST(root,NowNode->left,&(*NewRoot)->left);  
    if(NowNode->right)
      SupconvertBST(root,NowNode->right,&(*NewRoot)->right);  
}

struct TreeNode* convertBST(struct TreeNode * root) {
    if(!root)
        return root;
    struct TreeNode * NewRoot;
    SupconvertBST(root,root,&NewRoot);
    return NewRoot;
}
但是速度依然比较慢,大概是Solution 1的2-3倍速度。

Solution 3:
BST树的逆序遍历,因为本题我们可以发现,如果我们将节点保存在一个数组中,按升序排列,那么我们只需要从后往前求和,一次循环就可完成。基于这一思想,我们直接对BST树进行逆序遍历,也就是从最大的节点开始遍历(因为BST树就相当于一个有序的数组)我们只需要从右子树开始递归就行了。
void Sup(struct TreeNode * root,int *Sum)
{
    if(!root)
        return;
    Sup(root->right,Sum);
    (*Sum) = (*Sum)+root->val;
    root->val = (*Sum);
    Sup(root->left,Sum);
}

struct TreeNode* convertBST(struct TreeNode * root) {
    if(!root)
        return root;
    int sum = 0;
    Sup(root,&sum);
    return root;
}

例题三、

为了方便传输和存储,我们需要对BST树进行序列化。
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.
注意数据可能是1234,需要分解成字符串

Solution 1:
思想是,直接遍历BST树,记录其创建的时候输入的序列,(如前序递归创建的序列等),再需要的时候利用该序列进行重建。

int GetDeep(struct TreeNode* root)
{
    if(!root)
        return 0;
    int left,right;
    left = GetDeep(root->left);
    right = GetDeep(root->right);
    return (left > right ? (left+1) : (right+1));
}

//因为val可能是很多位,所以需要分割装填
void ValInData(int val,char *data,int *count)
{
    //直接逆序装填,解码的时候更加方便
    while(val > 0)
    {
        data[(*count)++] = val%10+48;
        val = val / 10;
    }
    data[(*count)++] = '*';
}

//解码出数字
int ValFromData(char *data,int *count)
{
    int val = 0,i = 0;
    while(data[*count]!='*')
        val = val + (data[(*count)++]-48) * (int)pow(10,i++);
    //跳过*
    (*count)++;
    return val;
}

void FillIn(struct TreeNode *root,char *data,int *count)
{
    if(!root)
    {
        //表示空
        data[(*count)++] = '#';
        return;
    }
    ValInData(root->val,data,count);
    FillIn(root->left,data,count);
    FillIn(root->right,data,count);
}

char* serialize(struct TreeNode* root) {
    int size = (int)pow(2,(GetDeep(root)+1));
    int count = 0;
    char *data = (char *)malloc(sizeof(char)*1000000000);
    FillIn(root,data,&count);
    data[count] = '\0';
    return data;
}

void CreateTree(struct TreeNode **root,char *data,int *count)
{
    if(data[*count] == '#')
    {
        *root = NULL;
        (*count)++;
    }
    else
    {
        (*root) = (struct TreeNode *)malloc(sizeof(struct TreeNode));     
        (*root)->val = ValFromData(data,count);
        (*root)->left = (*root)->right = NULL;
        CreateTree(&(*root)->left,data,count);
        CreateTree(&(*root)->right,data,count);
    }
}

/** Decodes your encoded data to tree. */
struct TreeNode* deserialize(char* data) {
    struct TreeNode *root;
    int count = 0;
    CreateTree(&root,data,&count);
    return root;
}

例题四:

For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.

Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).

You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Input: n = 4, edges = [[1, 0], [1, 2], [1, 3]]

        0
        |
        1
       / \
      2   3 

Output: [1]

Input: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]

     0  1  2
      \ | /
        3
        |
        4
        |
        5 

Output: [3, 4]

Solution 1:将问题简化,由于这是无圈的无向图,所以其实就是找该无向图的中心,那么我们就可以简化问题,不停的从叶子节点往中心靠,最后的一个或者两个节点就是最小的树根节点。因为如果中心含有3个及以上的节点,通过画图我们很容易看一看出其必定还可以简化成两个或者一个的情况。
typedef struct node{
   int Numbers;
   int Degree;
}NodeMes;


//录入度信息
NodeMes * InitNodeMes(int n,int** edges)
{
    NodeMes * Recorder = (NodeMes *)malloc(sizeof(NodeMes)*n);
    for(int k = 0;k < n;k++)
        Recorder[k].Degree = 0;
    for(int i = 0;i < n;i++)
    {
        for(int j = 0;j < n-1;j++)
        {
            if(edges[j][0] == i)
            {
                Recorder[i].Numbers = i;
                Recorder[i].Degree++;
            }
            else if(edges[j][1] == i)
            {
                Recorder[i].Numbers = i;
                Recorder[i].Degree++;
            }
        }//end of for
    }//end of for
    return Recorder;
}

int GetLeafeNumbers(NodeMes *Recorder,int n)
{
    int Count = 0;
    for(int i = 0;i < n;i++)
    {
        if(Recorder[i].Degree == 1 || Recorder[i].Degree == 0)
            Count++;
    }
    return Count;
}

NodeMes * CutLeafe(int** edges,NodeMes *Recorder,int n)
{
    int *flag = (int *)malloc(sizeof(int)*n);
    int i,j;
    for(i = 0;i < n;i++)
        flag[i] = -1;
    for(i = 0;i < n;i++)
    {
        if(Recorder[i].Degree == 1)
            flag[i] = 1;
    }
    for(i = 0;i < n;i++)
    {
        if(flag[i] == 1)
        {
            Recorder[i].Degree = -1;
            for(j = 0;j < n-1;j++)
            {
                if(edges[j][0] == Recorder[i].Numbers)
                {
                    Recorder[edges[j][1]].Degree--;
                    edges[j][0] = edges[j][1] = -1;
                }
                else if(edges[j][1] == Recorder[i].Numbers)
                {
                    Recorder[edges[j][0]].Degree--;
                    edges[j][0] = edges[j][1] = -1;
                }
            }
        }
    }
    return Recorder;
}

int* findMinHeightTrees(int n, int** edges, int edgesRowSize, int edgesColSize, int* returnSize) {
    if(n == 0)
        return NULL;
    if(n == 1)
    {
        int *A = (int *)malloc(sizeof(int));
        (* returnSize) = 1;
        A[0] = 0;
        return A;
    }
    NodeMes *Recorder = (NodeMes*)malloc(sizeof(NodeMes)*n);
    Recorder = InitNodeMes(n,edges);
    while(GetLeafeNumbers(Recorder,n) > 2)
        Recorder = CutLeafe(edges,Recorder,n);
    bool flag = false;
    int k;
    while(GetLeafeNumbers(Recorder,n) != 1 && !flag)
    {
        for(int i = 0;i < n && !flag;i++)
        {
            if(Recorder[i].Degree == 1)
            {
                for(k = 0;k < n-1;k++)
                {
                    if(edges[k][0] == Recorder[i].Numbers)
                    {
                        if(Recorder[edges[k][1]].Degree == 1)
                        {
                            flag = true;
                            break;
                        }
                    }
                    else if(edges[k][1] == Recorder[i].Numbers)
                    {
                        if(Recorder[edges[k][0]].Degree == 1)
                        {
                            flag = true;
                            break;
                        }
                    }
                }//end of for
            }
        }//end of for
        if(!flag)
            Recorder = CutLeafe(edges,Recorder,n);
    }
    if(!flag)
    {
        (*returnSize) = 1;
        int *result = (int *)malloc(sizeof(int));
        for(int i = 0;i < n;i++)
        {
            if(Recorder[i].Degree == 0)
            {
                result[0] = Recorder[i].Numbers;
                break;
            }
        }
        return result;
    }
    else
    {
        (*returnSize) = 2;
        int *result = (int *)malloc(sizeof(int)*2);
        int count = 0;
        for(int i = 0;i < n;i++)
        {
            if(Recorder[i].Degree == 1)
            {
                result[count++] = Recorder[i].Numbers;
            }
        }
        return result;
    }
}

例题五:

每个节点的倾斜度是该节点的左子树的数据和减去右子树的数据和
总的倾斜度是每隔节点的倾斜度的和

Solution:
采用递归的方法可以很容易的解决
//本节点及下面所有节点
int SumAll(struct TreeNode *root)
{
    if(!root)
        return 0;
    return (root->val+SumAll(root->left)+SumAll(root->right)); 
}

int findTilt(struct TreeNode* root) {
    if(!root)
        return 0;
    else if(!root->left && root->right)
        return (fabs(SumAll(root->right))+findTilt(root->right));
    else if(!root->right && root->left)
        return (fabs(SumAll(root->left))+findTilt(root->left));
    else 
        return (fabs(SumAll(root->left)-SumAll(root->right))+findTilt(root->left)+findTilt(root->right));
}

例题六、

Given an integer array with no duplicates. A maximum tree building on this array is defined as follow:

The root is the maximum number in the array.
The left subtree is the maximum tree constructed from left part subarray divided by the maximum number.
The right subtree is the maximum tree constructed from right part subarray divided by the maximum number.
Construct the maximum tree by the given array and output the root node of this tree.

Solution:利用树的结构是相似的,那么我们可以采用递归的方法解决。
int GetMax(int start,int end,int *nums,int *Max)
{
    int i,Index;
    (*Max) = -100;
    for(i = start;i <= end;i++)
    {
        if(nums[i] > (*Max))
        {
            (*Max) = nums[i];
            Index = i;
        }
    }
    return Index;
}

struct TreeNode *CreateTree(int start,int end,int *nums)
{
    if(start > end)
        return NULL;
    struct TreeNode * Temp = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    int Index = GetMax(start,end,nums,&Temp->val);
    Temp->left = CreateTree(start,Index-1,nums);
    Temp->right = CreateTree(Index+1,end,nums);
    return Temp;
}

struct TreeNode* constructMaximumBinaryTree(int* nums, int numsSize) {
    if(numsSize == 0)
        return NULL;
    int start,end;
    start = 0;
    end = numsSize-1;
    struct TreeNode *root = CreateTree(start,end,nums);
    return root;
}

例题七、

//层次输入数据进行树的创建
struct TreeNode * LevelOrderCreateTree(int *data,int dataSize)
{
    struct TreeNode ** Temp = (struct TreeNode **)malloc(sizeof(struct TreeNode *)*dataSize);
    int i;
    for(i = 0;i < dataSize;i++)
        (*Temp) = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    int TempCount = 0;
    int count = 0;
    int SonCount = 0;
    while(count < dataSize)
    {
        if(data[count] == -100)
        {
            struct TreeNode *T = NULL;
            count++;
            if(SonCount == 0)
            {
                Temp[0]->left = T;
                SonCount++;
            }
            else if(SonCount == 1)
            {
                Temp[0]->right = T;
                SonCount = 0;
                for(int j = 0;j < count-1;j++)
                    Temp[j] = Temp[j+1];
                TempCount--;
            }
        }
        else if(count == 0)
        {
            root->val = data[count++];
            root->left = root->right = NULL;
            Temp[TempCount++] = root;
        }
        else
        {
            struct TreeNode *T = (struct TreeNode *)malloc(sizeof(struct TreeNode));
            T->val = data[count++];
            T->left = T->right = NULL;
            Temp[TempCount++] = T;
            if(SonCount == 0)
            {
                Temp[0]->left = T;
                SonCount++;
            }
            else if(SonCount == 1)
            {
                Temp[0]->right = T;
                SonCount = 0;
                for(int j = 0;j < count-1;j++)
                    Temp[j] = Temp[j+1];
                TempCount--;
            }
        }
    }//end of while
    return root;
}

例题八、

Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n?

Solution :
采用动态规划的方法是可以很好的解决该问题的。
int numTrees(int n) {
    int * nums = (int *)malloc(sizeof(int)*(n+1));
    nums[0] = nums[1] = 1;
    int i,j;
    //计算出nums数组的每一个数据
    for(i = 2;i <= n;i++)
    {
        nums[i] = 0;
        //计算每一个nums[n]
        for(j = 0;j < i;j++)
            nums[i] += nums[j] * nums[i-j-1];
    }
    return nums[n];
}

例题九、

给一个指定的数N,相当于给1,2,3.....N的数组,我们需要给出该数列的所有的可能的BST树,返回根节点即可:

Solution :
采用分治的思想,我们从头开始每次选取 i 作为结点,那么(1,i-1)区间就是左子树的区间,(i+1,N)就是右子树的区间。同理递归。

//此处采用的DP来计算返回值的个数。
int GetNums(int n)
{
    int *nums = (int *)malloc(sizeof(int)*(n+1));
    nums[0] = nums[1] = 1;
    int i,j;
    for(i = 2;i <= n;i++)
    {
        nums[i] = 0;
        for(j = 0;j < i;j++)
            nums[i] += nums[j]*nums[i-j-1];
    }  
    return nums[n];
}

//返回根节点数组
struct TreeNode** Generate(int start,int end)
{
    struct TreeNode ** Res;
    if(start > end)
    {
        Res = (struct TreeNode **)malloc(sizeof(struct TreeNode *));
        Res[0] = NULL;
    }
    else
    {
        Res = (struct TreeNode **)malloc(sizeof(struct TreeNode *)*GetNums(end));
        int count = 0;
        for(int i = start; i <= end;i++)
        {
            struct TreeNode ** left = Generate(start,i-1);
            struct TreeNode ** right = Generate(i+1,end);
        int leftSize = GetNums(i-start);
        int rightSize = GetNums(end-i);
            int m = 0,k = 0;
        for(m = 0;m < leftSize;m++)
        { 
        for(k = 0;k < rightSize;k++)
        {
              struct TreeNode * Temp = (struct TreeNode *)malloc(sizeof(struct TreeNode));
              Res[count++] = Temp;
              Temp->val = i;
              Temp->left = left[m];
              Temp->right = right[k];
        }
       }
        }//for
    }//else
    return Res;
}

struct TreeNode** generateTrees(int n, int* returnSize) {
    if(n == 0)
        return NULL;
    *returnSize = GetNums(n);
    return Generate(1,n);
}

猜你喜欢

转载自blog.csdn.net/c_living/article/details/81227077
BST