给定二进制搜索树的遍历顺序。任务是从给定的预定顺序打印二进制搜索树的叶节点。
例子:
Input : preorder[] = {890, 325, 290, 530, 965};
Output : 290 530 965
Explanation : Tree represented is,
890
/ \
325 965
/ \
290 530
Input : preorder[] = { 3, 2, 4 };
Output : 2 4
方法1 :(简单)
这个想法是找到Iorder,然后以预排序方式(使用有序和后序遍历)遍历树,同时遍历打印叶节点。
如何使用表示有序和预序遍历的两个数组以预序方式遍历?
我们迭代预排序数组,并为每个元素在顺序数组中找到该元素。对于搜索,我们可以使用二进制搜索,因为二进制搜索树的有序遍历始终是排序的。现在,对于预排序数组的每个元素,在二进制搜索中,我们设置范围[L,R]。
当L == R时,找到叶节点。因此,最初,对于预排序数组的第一个元素(即根),L = 0和R = n – 1。现在,要搜索根的左子树上的元素,请设置L = 0且R =根的索引–1。此外,对于右子树的所有元素,请设置L =根的索引+ 1和R = n -1 。
递归地,遵循此,直到L ==R。
以下是此方法的实现:
C++
// C++ program to print leaf node from
// preorder of binary search tree.
#include
using namespace std;
// Binary Search
int binarySearch(int inorder[], int l, int r, int d)
{
int mid = (l + r)>>1;
if (inorder[mid] == d)
return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l, mid - 1, d);
else
return binarySearch(inorder, mid + 1, r, d);
}
// Function to print Leaf Nodes by doing preorder
// traversal of tree using preorder and inorder arrays.
void leafNodesRec(int preorder[], int inorder[],
int l, int r, int *ind, int n)
{
// If l == r, therefore no right or left subtree.
// So, it must be leaf Node, print it.
if(l == r)
{
printf("%d ", inorder[l]);
*ind = *ind + 1;
return;
}
// If array is out of bound, return.
if (l < 0 || l > r || r >= n)
return;
// Finding the index of preorder element
// in inorder array using binary search.
int loc = binarySearch(inorder, l, r, preorder[*ind]);
// Incrementing the index.
*ind = *ind + 1;
// Finding on the left subtree.
leafNodesRec(preorder, inorder, l, loc - 1, ind, n);
// Finding on the right subtree.
leafNodesRec(preorder, inorder, loc + 1, r, ind, n);
}
// Finds leaf nodes from given preorder traversal.
void leafNodes(int preorder[], int n)
{
int inorder[n]; // To store inorder traversal
// Copy the preorder into another array.
for (int i = 0; i < n; i++)
inorder[i] = preorder[i];
// Finding the inorder by sorting the array.
sort(inorder, inorder + n);
// Point to the index in preorder.
int ind = 0;
// Print the Leaf Nodes.
leafNodesRec(preorder, inorder, 0, n - 1, &ind, n);
}
// Driven Program
int main()
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = sizeof(preorder)/sizeof(preorder[0]);
leafNodes(preorder, n);
return 0;
}
Java
// Java program to print leaf node from
// preorder of binary search tree.
import java.util.*;
class GFG
{
// Binary Search
static int binarySearch(int inorder[], int l,
int r, int d)
{
int mid = (l + r) >> 1;
if (inorder[mid] == d)
return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l,
mid - 1, d);
else
return binarySearch(inorder,
mid + 1, r, d);
}
// Point to the index in preorder.
static int ind;
// Function to print Leaf Nodes by
// doing preorder traversal of tree
// using preorder and inorder arrays.
static void leafNodesRec(int preorder[],
int inorder[],
int l, int r, int n)
{
// If l == r, therefore no right or left subtree.
// So, it must be leaf Node, print it.
if(l == r)
{
System.out.printf("%d ", inorder[l]);
ind = ind + 1;
return;
}
// If array is out of bound, return.
if (l < 0 || l > r || r >= n)
return;
// Finding the index of preorder element
// in inorder array using binary search.
int loc = binarySearch(inorder, l, r,
preorder[ind]);
// Incrementing the index.
ind = ind + 1;
// Finding on the left subtree.
leafNodesRec(preorder, inorder,
l, loc - 1, n);
// Finding on the right subtree.
leafNodesRec(preorder, inorder,
loc + 1, r, n);
}
// Finds leaf nodes from given preorder traversal.
static void leafNodes(int preorder[], int n)
{
// To store inorder traversal
int inorder[] = new int[n];
// Copy the preorder into another array.
for (int i = 0; i < n; i++)
inorder[i] = preorder[i];
// Finding the inorder by sorting the array.
Arrays.sort(inorder);
// Print the Leaf Nodes.
leafNodesRec(preorder, inorder, 0, n - 1, n);
}
// Driver Code
public static void main(String args[])
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = preorder.length;
leafNodes(preorder, n);
}
}
// This code is contributed by Arnab Kundu
Python3
# Python3 program to print leaf node from
# preorder of binary search tree.
# Binary Search
def binarySearch(inorder, l, r, d):
mid = (l + r) >> 1
if (inorder[mid] == d):
return mid
elif (inorder[mid] > d):
return binarySearch(inorder, l,
mid - 1, d)
else:
return binarySearch(inorder,
mid + 1, r, d)
# Function to prLeaf Nodes by doing
# preorder traversal of tree using
# preorder and inorder arrays.
def leafNodesRec(preorder, inorder,
l, r, ind, n):
# If l == r, therefore no right or left subtree.
# So, it must be leaf Node, print it.
if(l == r):
print(inorder[l], end = " ")
ind[0] = ind[0] + 1
return
# If array is out of bound, return.
if (l < 0 or l > r or r >= n):
return
# Finding the index of preorder element
# in inorder array using binary search.
loc = binarySearch(inorder, l, r,
preorder[ind[0]])
# Incrementing the index.
ind[0] = ind[0] + 1
# Finding on the left subtree.
leafNodesRec(preorder, inorder,
l, loc - 1, ind, n)
# Finding on the right subtree.
leafNodesRec(preorder, inorder,
loc + 1, r, ind, n)
# Finds leaf nodes from
# given preorder traversal.
def leafNodes(preorder, n):
# To store inorder traversal
inorder = [0] * n
# Copy the preorder into another array.
for i in range(n):
inorder[i] = preorder[i]
# Finding the inorder by sorting the array.
inorder.sort()
# Poto the index in preorder.
ind = [0]
# Print the Leaf Nodes.
leafNodesRec(preorder, inorder, 0,
n - 1, ind, n)
# Driver Code
preorder = [890, 325, 290, 530, 965]
n = len(preorder)
leafNodes(preorder, n)
# This code is contributed
# by SHUBHAMSINGH10
C#
// C# program to print leaf node from
// preorder of binary search tree.
using System;
class GFG
{
// Binary Search
static int binarySearch(int []inorder, int l,
int r, int d)
{
int mid = (l + r) >> 1;
if (inorder[mid] == d)
return mid;
else if (inorder[mid] > d)
return binarySearch(inorder, l,
mid - 1, d);
else
return binarySearch(inorder,
mid + 1, r, d);
}
// Point to the index in preorder.
static int ind;
// Function to print Leaf Nodes by
// doing preorder traversal of tree
// using preorder and inorder arrays.
static void leafNodesRec(int []preorder,
int []inorder,
int l, int r, int n)
{
// If l == r, therefore no right or left subtree.
// So, it must be leaf Node, print it.
if(l == r)
{
Console.Write("{0} ", inorder[l]);
ind = ind + 1;
return;
}
// If array is out of bound, return.
if (l < 0 || l > r || r >= n)
return;
// Finding the index of preorder element
// in inorder array using binary search.
int loc = binarySearch(inorder, l, r,
preorder[ind]);
// Incrementing the index.
ind = ind + 1;
// Finding on the left subtree.
leafNodesRec(preorder, inorder,
l, loc - 1, n);
// Finding on the right subtree.
leafNodesRec(preorder, inorder,
loc + 1, r, n);
}
// Finds leaf nodes from given preorder traversal.
static void leafNodes(int []preorder, int n)
{
// To store inorder traversal
int []inorder = new int[n];
// Copy the preorder into another array.
for (int i = 0; i < n; i++)
inorder[i] = preorder[i];
// Finding the inorder by sorting the array.
Array.Sort(inorder);
// Print the Leaf Nodes.
leafNodesRec(preorder, inorder, 0, n - 1, n);
}
// Driver Code
public static void Main(String []args)
{
int []preorder = { 890, 325, 290, 530, 965 };
int n = preorder.Length;
leafNodes(preorder, n);
}
}
// This code is contributed by Rajput-Ji
C++
// Stack based C++ program to print leaf nodes
// from preorder traversal.
#include
using namespace std;
// Print the leaf node from the given preorder of BST.
void leafNode(int preorder[], int n)
{
stack s;
for (int i = 0, j = 1; j < n; i++, j++)
{
bool found = false;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (!s.empty())
{
if (preorder[j] > s.top())
{
s.pop();
found = true;
}
else
break;
}
}
if (found)
cout << preorder[i] << " ";
}
// Since rightmost element is always leaf node.
cout << preorder[n - 1];
}
// Driver code
int main()
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = sizeof(preorder)/sizeof(preorder[0]);
leafNode(preorder, n);
return 0;
}
Java
// Stack based Java program to print leaf nodes
// from preorder traversal.
import java.util.*;
class GfG {
// Print the leaf node from the given preorder of BST.
static void leafNode(int preorder[], int n)
{
Stack s = new Stack ();
for (int i = 0, j = 1; j < n; i++, j++)
{
boolean found = false;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (!s.isEmpty())
{
if (preorder[j] > s.peek())
{
s.pop();
found = true;
}
else
break;
}
}
if (found)
System.out.print(preorder[i] + " ");
}
// Since rightmost element is always leaf node.
System.out.println(preorder[n - 1]);
}
// Driver code
public static void main(String[] args)
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = preorder.length;
leafNode(preorder, n);
}
}
Python3
# Stack based Python program to print
# leaf nodes from preorder traversal.
# Print the leaf node from the given
# preorder of BST.
def leafNode(preorder, n):
s = []
i = 0
for j in range(1, n):
found = False
if preorder[i] > preorder[j]:
s.append(preorder[i])
else:
while len(s) != 0:
if preorder[j] > s[-1]:
s.pop(-1)
found = True
else:
break
if found:
print(preorder[i], end = " ")
i += 1
# Since rightmost element is
# always leaf node.
print(preorder[n - 1])
# Driver code
if __name__ == '__main__':
preorder = [890, 325, 290, 530, 965]
n = len(preorder)
leafNode(preorder, n)
# This code is contributed by PranchalK
C#
using System;
using System.Collections.Generic;
// Stack based C# program to print leaf nodes
// from preorder traversal.
public class GfG
{
// Print the leaf node from the given preorder of BST.
public static void leafNode(int[] preorder, int n)
{
Stack s = new Stack ();
for (int i = 0, j = 1; j < n; i++, j++)
{
bool found = false;
if (preorder[i] > preorder[j])
{
s.Push(preorder[i]);
}
else
{
while (s.Count > 0)
{
if (preorder[j] > s.Peek())
{
s.Pop();
found = true;
}
else
{
break;
}
}
}
if (found)
{
Console.Write(preorder[i] + " ");
}
}
// Since rightmost element is always leaf node.
Console.WriteLine(preorder[n - 1]);
}
// Driver code
public static void Main(string[] args)
{
int[] preorder = new int[] {890, 325, 290, 530, 965};
int n = preorder.Length;
leafNode(preorder, n);
}
}
// This code is contributed by Shrikant13
输出:
290 530 965
时间复杂度: O(n log n)
辅助空间: O(n)
方法2 :(使用堆栈)
这个想法是使用二进制搜索树和堆栈的属性。
使用两个指向数组的指针i和j遍历数组,最初i = 0和j =1。每当a [i]> a [j]时,我们可以说a [j]是a [i]的左部分,因为顺序遍历遵循“访问”->“左”->“右”。因此,我们将a [i]推入堆栈。
对于违反规则的那些点,我们开始从堆栈中弹出元素,直到a [i]>堆栈的顶部元素,然后在不出现时断开,并打印相应的第j个值。
算法:
1. Set i = 0, j = 1.
2. Traverse the preorder array.
3. If a[i] > a[j], push a[i] to the stack.
4. Else
While (stack is not empty)
if (a[j] > top of stack)
pop element from the stack;
set found = true;
else
break;
5. if (found == true)
print a[i];
该算法如何工作?
顺序遍历遍历的顺序为:访问,向左,向右。
而且我们知道BST中任何节点的左节点始终小于该节点。因此,预遍历将首先从根节点遍历到最左边的节点。因此,预排序将首先以降序排列。现在,在降序之后,可能存在一个更大的节点或打破了降序的节点。因此,可能会有这样的情况:
在情况1中,20是叶节点,而在情况2中,20不是叶节点。
因此,我们的问题是如何确定是否必须将20打印为叶节点?
这是使用堆栈解决的。
在情况1和情况2上运行上述算法时,当i = 2和j = 3时,两种情况下的堆栈状态都相同:
因此,节点65将从堆栈中弹出20和50。这是因为65是20之前的节点的右子节点。我们使用找到的变量存储此信息。因此,20是一个根节点。
在第2种情况下,40将无法从堆栈中弹出任何元素。因为40是20之后的节点的右节点,所以20不是叶节点。
注意:在算法中,我们将无法检查最右节点或预排序中最右元素的叶节点的状况。因此,只需打印最右边的节点,因为我们知道在预遍历中这将始终是叶节点。
以下是此方法的实现:
C++
// Stack based C++ program to print leaf nodes
// from preorder traversal.
#include
using namespace std;
// Print the leaf node from the given preorder of BST.
void leafNode(int preorder[], int n)
{
stack s;
for (int i = 0, j = 1; j < n; i++, j++)
{
bool found = false;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (!s.empty())
{
if (preorder[j] > s.top())
{
s.pop();
found = true;
}
else
break;
}
}
if (found)
cout << preorder[i] << " ";
}
// Since rightmost element is always leaf node.
cout << preorder[n - 1];
}
// Driver code
int main()
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = sizeof(preorder)/sizeof(preorder[0]);
leafNode(preorder, n);
return 0;
}
Java
// Stack based Java program to print leaf nodes
// from preorder traversal.
import java.util.*;
class GfG {
// Print the leaf node from the given preorder of BST.
static void leafNode(int preorder[], int n)
{
Stack s = new Stack ();
for (int i = 0, j = 1; j < n; i++, j++)
{
boolean found = false;
if (preorder[i] > preorder[j])
s.push(preorder[i]);
else
{
while (!s.isEmpty())
{
if (preorder[j] > s.peek())
{
s.pop();
found = true;
}
else
break;
}
}
if (found)
System.out.print(preorder[i] + " ");
}
// Since rightmost element is always leaf node.
System.out.println(preorder[n - 1]);
}
// Driver code
public static void main(String[] args)
{
int preorder[] = { 890, 325, 290, 530, 965 };
int n = preorder.length;
leafNode(preorder, n);
}
}
Python3
# Stack based Python program to print
# leaf nodes from preorder traversal.
# Print the leaf node from the given
# preorder of BST.
def leafNode(preorder, n):
s = []
i = 0
for j in range(1, n):
found = False
if preorder[i] > preorder[j]:
s.append(preorder[i])
else:
while len(s) != 0:
if preorder[j] > s[-1]:
s.pop(-1)
found = True
else:
break
if found:
print(preorder[i], end = " ")
i += 1
# Since rightmost element is
# always leaf node.
print(preorder[n - 1])
# Driver code
if __name__ == '__main__':
preorder = [890, 325, 290, 530, 965]
n = len(preorder)
leafNode(preorder, n)
# This code is contributed by PranchalK
C#
using System;
using System.Collections.Generic;
// Stack based C# program to print leaf nodes
// from preorder traversal.
public class GfG
{
// Print the leaf node from the given preorder of BST.
public static void leafNode(int[] preorder, int n)
{
Stack s = new Stack ();
for (int i = 0, j = 1; j < n; i++, j++)
{
bool found = false;
if (preorder[i] > preorder[j])
{
s.Push(preorder[i]);
}
else
{
while (s.Count > 0)
{
if (preorder[j] > s.Peek())
{
s.Pop();
found = true;
}
else
{
break;
}
}
}
if (found)
{
Console.Write(preorder[i] + " ");
}
}
// Since rightmost element is always leaf node.
Console.WriteLine(preorder[n - 1]);
}
// Driver code
public static void Main(string[] args)
{
int[] preorder = new int[] {890, 325, 290, 530, 965};
int n = preorder.Length;
leafNode(preorder, n);
}
}
// This code is contributed by Shrikant13
输出:
290 530 965
时间复杂度: O(n)
二叉搜索树的预排序中的叶节点(使用递归)