📜  将二叉树转换为二叉搜索树所需的最小交换

📅  最后修改于: 2021-04-23 16:07:56             🧑  作者: Mango

给定完整二叉树的数组表示形式,即,如果索引i是父级,则索引2 * i + 1是左子级,索引2 * i + 2是右子级。任务是找到将其转换为二进制搜索树所需的最小交换次数。

例子:

Input : arr[] = { 5, 6, 7, 8, 9, 10, 11 }
Output : 3
Binary tree of the given array:

挖11

Swap 1: Swap node 8 with node 5.
Swap 2: Swap node 9 with node 10.
Swap 3: Swap node 10 with node 7.

挖21

So, minimum 3 swaps are required.


Input : arr[] = { 1, 2, 3 }
Output : 1
Binary tree of the given array:

挖3

After swapping node 1 with node 2.

挖41

So, only 1 swap required.

这个想法是利用二进制搜索树的顺序遍历以其值的升序的事实。
因此,找到二叉树的有序遍历并将其存储在数组中并尝试对数组进行排序。答案是使阵列排序所需的最少交换次数。请参考下面的帖子,以找到对数组进行排序所需的最小交换次数。
排序数组所需的最小交换次数
时间复杂度: O(n log n)。

C++
// C++ program for Minimum swap required
// to convert binary tree to binary search tree
#include
using namespace std;
 
// Inorder Traversal of Binary Tree
void inorder(int a[], std::vector &v,
                        int n, int index)
{
    // if index is greater or equal to vector size
    if(index >= n)
        return;
    inorder(a, v, n, 2 * index + 1);
     
    // push elements in vector
    v.push_back(a[index]);
    inorder(a, v, n, 2 * index + 2);
}
 
// Function to find minimum swaps to sort an array
int minSwaps(std::vector &v)
{
    std::vector > t(v.size());
    int ans = 0;
    for(int i = 0; i < v.size(); i++)
        t[i].first = v[i], t[i].second = i;
     
    sort(t.begin(), t.end());
    for(int i = 0; i < t.size(); i++)
    {
        // second element is equal to i
        if(i == t[i].second)
            continue;
        else
        {
            // swaping of elements
            swap(t[i].first, t[t[i].second].first);
            swap(t[i].second, t[t[i].second].second);
        }
         
        // Second is not equal to i
        if(i != t[i].second)
            --i;
        ans++;
    }
    return ans;
}
 
// Driver code
int main()
{
    int a[] = { 5, 6, 7, 8, 9, 10, 11 };
    int n = sizeof(a) / sizeof(a[0]);
    std::vector v;
    inorder(a, v, n, 0);
    cout << minSwaps(v) << endl;
}
 
// This code is contributed by code_freak


Python3
# Python3 program for Minimum swap required
# to convert binary tree to binary search tree
 
# Inorder Traversal of Binary Tree
def inorder(a, n, index):
     
    global v
     
    # If index is greater or equal to
    # vector size
    if (index >= n):
        return
     
    inorder(a, n, 2 * index + 1)
 
    # Push elements in vector
    v.append(a[index])
    inorder(a, n, 2 * index + 2)
 
# Function to find minimum swaps
# to sort an array
def minSwaps():
     
    global v
    t = [[0, 0] for i in range(len(v))]
    ans = -2
 
    for i in range(len(v)):
        t[i][0], t[i][1] = v[i], i
 
    t, i = sorted(t), 0
 
    while i < len(t):
         
        # break
        # second element is equal to i
        if (i == t[i][1]):
            i += 1
            continue
        else:
             
            # Swaping of elements
            t[i][0], t[t[i][1]][0] = t[t[i][1]][0], t[i][0]
            t[i][1], t[t[i][1]][1] = t[t[i][1]][1], t[i][1]
 
        # Second is not equal to i
        if (i == t[i][1]):
            i -= 1
 
        i += 1
 
        ans += 1
 
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    v = []
    a = [ 5, 6, 7, 8, 9, 10, 11 ]
    n = len(a)
    inorder(a, n, 0)
 
    print(minSwaps())
 
# This code is contributed by mohit kumar 29


输出:

3

练习:我们可以将其扩展到普通的二叉树,即用左右指针表示的二叉树,不一定完整吗?