Algorithm 如何将二叉树转换为二叉搜索树,也就是说,我们不能使用任何额外的空间
如何将二叉树转换为二叉搜索树,也就是说,我们不能使用任何额外的空间 二叉树通常是二叉搜索树,在这种情况下不需要转换Algorithm 如何将二叉树转换为二叉搜索树,也就是说,我们不能使用任何额外的空间,algorithm,data-structures,tree,binary-tree,binary-search-tree,Algorithm,Data Structures,Tree,Binary Tree,Binary Search Tree,如何将二叉树转换为二叉搜索树,也就是说,我们不能使用任何额外的空间 二叉树通常是二叉搜索树,在这种情况下不需要转换 也许你需要澄清你正在转换的内容的结构。您的源代码树是否不平衡?它不是按您要搜索的密钥排序的吗?你是如何找到源代码树的?如果这是一个采访问题,我会脱口而出的第一件事(没有实际想法)是:递归地迭代整个二进制文件,然后找到最小的元素。把它从二叉树中去掉。现在,重复这个过程,迭代整个树并找到最小的元素,并将其添加为找到的最后一个元素的父元素(前一个元素成为新节点的左子元素)。根据需要重复多
也许你需要澄清你正在转换的内容的结构。您的源代码树是否不平衡?它不是按您要搜索的密钥排序的吗?你是如何找到源代码树的?如果这是一个采访问题,我会脱口而出的第一件事(没有实际想法)是:递归地迭代整个二进制文件,然后找到最小的元素。把它从二叉树中去掉。现在,重复这个过程,迭代整个树并找到最小的元素,并将其添加为找到的最后一个元素的父元素(前一个元素成为新节点的左子元素)。根据需要重复多次,直到原始树为空。最后,剩下的是最差的排序二叉树——链表。您的指针指向根节点,它是最大的元素
这是一个非常糟糕的算法,运行时间为O(n^2),二叉树输出可能最差,但在想出更好的算法之前,这是一个不错的起点,它的优点是你可以在白板上用大约20行代码来编写它。你不需要付出太多努力,但是,如果需求是我认为的,那么您已经创建了一个二叉树,它位于内存中,但没有排序(不管怎样,您希望以什么方式排序) 我假设树节点看起来像
struct tree_node {
struct tree_node * left;
struct tree_node * right;
data_t data;
};
我还假设你能读C
我们可以坐在那里想,为什么这棵树没有按排序顺序创建,这对我们没有任何好处,所以我将忽略它,只处理排序问题
不使用额外空间的要求很奇怪。暂时会有额外的空间,如果只是在堆栈上。我将假设这意味着调用malloc或类似的东西,并且生成的树不需要使用比原始未排序树更多的内存
第一个也是最简单的解决方案是对未排序的树进行预排序遍历,从该树中删除每个节点,并将排序后的插入到新树中。这是O(n+nlog(n)),也就是O(nlog(n))
如果这不是他们想要的,你必须使用旋转和其他方法。。。。。太可怕了
我以为可以通过执行堆排序的奇怪版本来实现这一点,但我遇到了问题。
另一件事出现在我的脑海里,速度非常慢,那就是在树上做一个奇怪的泡泡排序
为此,将对每个节点进行比较,并可能与它的每个直接子节点(因此也与其父节点)重复交换,直到您遍历该树并没有找到任何节点为止
需要互换。执行shaker排序(从左到右和从右到左的气泡排序)版本效果最好,并且在初始传递之后,您不需要向下遍历子树,这些子树看起来不会与其父树的顺序不符
我敢肯定,要么这个算法是我之前的其他人想出的,有一个我不知道的酷名字,要么它在某种程度上有根本性的缺陷,我看不出来
第二个建议的运行时计算相当复杂。起初,我认为它只是O(n^2),就像气泡和振动筛排序一样,但我不能满足自己的要求,子树遍历避免可能不足以使它比O(n^2)好一点。基本上,气泡和振动筛分类也得到了这种优化,但只有在总分类提前出现的末端,你才能削减限制。使用此树版本,您可以获得避免在集合中间的块的可能性。就像我说的,它可能有致命的缺陷。按顺序遍历二叉树并存储结果。 按顺序对结果排序
通过将排序列表的中间元素作为根来形成二元搜索树(这可以使用二元搜索完成)。因此,我们得到了平衡的二叉搜索树。执行以下算法以获得解决方案
struct Node * newroot = '\0';
struct Node* PostOrder(Struct Node* root)
{
if(root != '\0')
{
PostOrder(root->left);
PostOrder(root->right);
insertBST(root, &newroot);
}
}
insertBST(struct Node* node, struct Node** root)
{
struct Node * temp, *temp1;
if( root == '\0')
{
*root == node;
node->left == '\0';
node->right == '\0';
}
else
{
temp = *root;
while( temp != '\0')
{
temp1= temp;
if( temp->data > node->data)
temp = temp->left;
else
temp = temp->right;
}
if(temp1->data > node->data)
{
temp1->left = node;
}
else
{
temp1->right = node;
}
node->left = node->right = '\0';
}
}
1) 在不使用任何空格的情况下查找顺序后续项
Node InOrderSuccessor(Node node)
{
if (node.right() != null)
{
node = node.right()
while (node.left() != null)
node = node.left()
return node
}
else
{
parent = node.getParent();
while (parent != null && parent.right() == node)
{
node = parent
parent = node.getParent()
}
return parent
}
}
2) 在不使用空格的情况下按顺序遍历
a) 查找顺序遍历的第一个节点。它应该是树的最左边的子级(如果有),或者是第一个右边的子级的左边(如果有),或者右边的子级本身。
b) 使用上述算法查找第一个节点的后续节点。
c) 对所有返回的后继对象重复步骤2
使用上述2种算法,在不使用额外空间的情况下对二叉树进行顺序遍历。
进行遍历时,形成二叉搜索树。但是复杂性是O(N2)最坏的情况。对树进行堆排序。。nlogn complexity..执行后序遍历,并从中创建二叉搜索树
struct Node * newroot = '\0';
struct Node* PostOrder(Struct Node* root)
{
if(root != '\0')
{
PostOrder(root->left);
PostOrder(root->right);
insertBST(root, &newroot);
}
}
insertBST(struct Node* node, struct Node** root)
{
struct Node * temp, *temp1;
if( root == '\0')
{
*root == node;
node->left == '\0';
node->right == '\0';
}
else
{
temp = *root;
while( temp != '\0')
{
temp1= temp;
if( temp->data > node->data)
temp = temp->left;
else
temp = temp->right;
}
if(temp1->data > node->data)
{
temp1->left = node;
}
else
{
temp1->right = node;
}
node->left = node->right = '\0';
}
}
将二叉树转换为双链表-可以在O(n)中就地完成
然后使用合并排序,nlogn
将列表转换回树-O(n) 简单的nlogn解决方案。
#包括
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
struct tree_node {
struct tree_node * left;
struct tree_node * right;
data_t data;
};
/* a bonsai-tree for testing */
struct tree_node nodes[10] =
{{ nodes+1, nodes+2, 1}
,{ nodes+3, nodes+4, 2}
,{ nodes+5, nodes+6, 3}
,{ nodes+7, nodes+8, 4}
,{ nodes+9, NULL, 5}
,{ NULL, NULL, 6}
,{ NULL, NULL, 7}
,{ NULL, NULL, 8}
,{ NULL, NULL, 9}
};
struct tree_node * harvest(struct tree_node **hnd)
{
struct tree_node *ret;
while (ret = *hnd) {
if (!ret->left && !ret->right) {
*hnd = NULL;
return ret;
}
if (!ret->left ) {
*hnd = ret->right;
ret->right = NULL;;
return ret;
}
if (!ret->right) {
*hnd = ret->left;
ret->left = NULL;;
return ret;
}
hnd = (rand() &1) ? &ret->left : &ret->right;
}
return NULL;
}
void insert(struct tree_node **hnd, struct tree_node *this)
{
struct tree_node *ret;
while ((ret= *hnd)) {
hnd = (this->data < ret->data ) ? &ret->left : &ret->right;
}
*hnd = this;
}
void show(struct tree_node *ptr, int indent)
{
if (!ptr) { printf("Null\n"); return; }
printf("Node(%d):\n", ptr->data);
printf("%*c=", indent, 'L'); show (ptr->left, indent+2);
printf("%*c=", indent, 'R'); show (ptr->right, indent+2);
}
int main(void)
{
struct tree_node *root, *this, *new=NULL;
for (root = &nodes[0]; this = harvest (&root); ) {
insert (&new, this);
}
show (new, 0);
return 0;
}
#包括
typedef int data_t;
结构树节点{
结构树节点*左;
结构树_节点*右;
数据;
};
/*测试用盆景树*/
结构树_节点节点[10]=
{{节点+1,节点+2,1}
,{nodes+3,nodes+4,2}
,{nodes+5,nodes+6,3}
,{nodes+7,nodes+8,4}
,{nodes+9,NULL,5}
,{NULL,NULL,6}
,{NULL,NULL,7}
,{NULL,NULL,8}
,{NULL,NULL,9}
};
结构树节点*收获(结构树节点**hnd)
{
结构树节点*ret;
而(ret=*hnd){
如果(!ret->left&&!ret->right){
*hnd=NULL;
返回ret;
}
如果(!ret->left){
*hnd=ret->右侧;
ret->right=NULL;;
***I am giving this solution in Java***
import javafx.util.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
public class MinimumSwapRequiredBTintoBST {
//Node of binary tree
public static class Node{
int data;
Node left;
Node right;
public Node(int data){
this.data = data;
this.left = null;
this.right = null;
}
}
public static void main(String []arg){
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
System.out.print("Tree traverasl i.e inorder traversal :");
inorder(root);
System.out.println(" ");
MinimumSwapRequiredBTintoBST bst = new MinimumSwapRequiredBTintoBST();
bst.convertBTBST(root);
}
private static void inorder(Node root) {
if(root == null) return;
inorder(root.left);
System.out.print(root.data + " ");
inorder(root.right);
}
static Node root;
int[] treeArray;
int index = 0;
// convert binary tree to binary search tree
public void convertBTBST(Node node){
int treeSize = elementsOfTree(node);
treeArray = new int[treeSize];
convertBtToArray(node);
// Sort Array ,Count number of swap
int minSwap = minimumswap(treeArray);
System.out.println("Minmum swap required to form BT to BST :" +minSwap);
}
private static int minimumswap(int[] arr) {
int n =arr.length;
// Create two arrays and use as pairs where first
// is element and secount array as position of first element
ArrayList<Pair<Integer, Integer>> arrpos =
new ArrayList<Pair<Integer, Integer>>();
// Assign the value
for(int i =0;i<n;i++)
{
arrpos.add(new Pair<Integer, Integer>(arr[i],i));
}
// Sort the array by array element values to get right
//position of every element as the elements of secound array
arrpos.sort(new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> o1, Pair<Integer, Integer> o2) {
return o1.getKey()-o2.getKey();
}
});
// To keep track of visited elements .Initially all elements as not visited so put them as false
int ans = 0;
boolean []visited = new boolean[n];
Arrays.fill(visited, false);
// Traverse array elements
for(int i =0;i<n;i++){
// Already swapped and corrected or already present at correct pos
if(visited[i] || arrpos.get(i).getValue() == i)
continue;
// Find out the number of nodes in this cycle and add in ans
int cycle_size = 0;
int j =i;
while(!visited[j]){
visited[j] = true;
j = arrpos.get(j).getValue();
cycle_size++;
}
if(cycle_size>0){
ans += cycle_size-1;
}
}
return ans;
}
private void convertBtToArray(Node node) {
// Check whether tree is empty or not.
if (root == null) {
System.out.println("Tree is empty:");
return;
}
else{
if(node.left != null) {
convertBtToArray(node.left);}
treeArray[index] = node.data;
index++;
if(node.right != null){
convertBtToArray(node.right);
}
}
}
private int elementsOfTree(Node node) {
int height = 0;
if(node == null) return 0;
else{
height = elementsOfTree(node.left )+ elementsOfTree(node.right)+1;
}
return height;
}
}