печать уровня порядка обхода двоичного дерева зигзагом
Я должен распечатать узлы двоичного дерева, используя обход порядка уровней, но в спиральной форме i.e узлы на разных уровнях должны быть напечатаны в спиральной форме.
например: если дерево выглядит так:
на выходе должно быть 10 5 20 25 15 6 4.
алгоритм, который я использовал, прост и является лишь небольшим изменением обхода порядка уровней. Я просто взял переменную p.если переменная равна 1, то выведите ордер на заданном уровне слева справа, если это -1, выведите справа налево.
void getlevel(struct node *root,int n,int p)
{
if(root==NULL)
return;
if(n==0)
{
printf("%d ",root->info);
return;
}
if(n>0)
{
if(p==1)
{
getlevel(root->left,n-1,p);
getlevel(root->right,n-1,p);
}
if(p==-1)
{
getlevel(root->right,n-1,p);
getlevel(root->left,n-1,p);
}
}
}
Я получаю ответ, но в худшем случае сложность, вероятно, O (n^2) в случае искривленного дерева.
может быть лучший алгоритм для этой задачи?..
вся моя программа здесь
5 ответов
да.
вы можете сделать что-то похожее на обычный обход порядка уровней.
вы должны использовать два стека
- первый стек для печати слева направо
- второй стек для печати справа налево.
начните с корневого узла. Храните детей в одной стопке. На каждой итерации у вас есть узлы одного уровня в одном из стеков. Распечатайте узлы и нажмите узлы следующего уровня в другом стеке. Повторять пока не достигнете финального уровня.
временная сложность O(n) и пространственная сложность O (n).
Psuedocode для обхода порядка спирального уровня двоичного дерева.
//Define two stacks S1, S2
//At each level,
// S1 carries the nodes to be traversed in that level
// S2 carries the child nodes of the nodes in S1
spiralLevelOrder(root) {
S1 = new Stack()
S2 = new Stack()
S1.push(root)
spiralLevelOrderRecursion(S1, S2, 1)
}
spiralLevelOrderRecursion(S1, S2, level) {
while(S1 not empty) {
node = S1.pop()
visit(node)
if (level is odd) {
S2.push(node.rightNode)
S2.push(node.leftNode)
}
else {
S2.push(node.leftNode)
S2.push(node.rightNode)
}
}
if (S2 not empty)
spiralLevelOrderRecursion(S2, S1, level+1)
}
образец дерева : 1-(2-(4,5),3-(5,6)) формат: root - (leftchild, rightchild)
применение псевдокода :
spiralLevelOrderRecursion([1], [], 1)
S2 - [] -> [3] -> [2, 3]
visit order : 1
spiralLevelOrderRecursion([2,3], [], 2)
S2 - [] -> [4] -> [5,4] -> [6, 5, 4] -> [7, 6, 5, 4]
visit order : 2, 3
spiralLevelOrderRecursion([7,6,5,4], [], 3)
visit order : 7, 6, 5, 4
следующий код выполнит эту работу:
Используемый Язык: Java
// Algorithm for printing nodes in Zigzag order(zigzag tree traversal)
static void zigzagTreeTraversal(Node root)
{
int count=0,c=1,i=0;
boolean odd=false;
Queue<Node> queue=new LinkedList<Node>();
Node temp = null;
queue.add(root);
System.out.print("Printing Tree Traversal in Zigzag form :");
while(true)
{
if(queue.isEmpty())
{
break;
}
for(i=0;i<c;i++)
{
temp=queue.remove();
System.out.print(", " + temp.data);
if(odd)
{
if(temp.right!=null)
{
queue.add(temp.right);
count++;
}
if(temp.left!=null)
{
queue.add(temp.left);
count++;
}
}
else
{
if(temp.left!=null)
{
queue.add(temp.left);
count++;
}
if(temp.right!=null)
{
queue.add(temp.right);
count++;
}
}
}
c=count;
count=0;
odd=!odd;
}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;
public class ZigZagTraversal {
public static void main(String[] args) {
// TODO Auto-generated method stub
BinaryTree bt = new BinaryTree();
int[] array = {2,5,1,3,11,7,8,9,4,10,6};
/*
* 2
* / \
* / \
* / \
* 5 1
* / \ / \
* / \ / \
* 3 11 7 8
* / \ / \
* 9 4 10 6
*
* */
bt=BinaryTree.buildATree(bt, array);
//BinaryTree.inOrderTraversal(bt);
zigZagTraversal(llForAllNodesAtEachDepth(bt));
zigZagDisplay(bt);
}
public static void zigZagDisplay(BinaryTree bt){
Stack<BinaryTree> s = new Stack<>();
if(s.isEmpty())
s.push(bt);
boolean flag = true;
while(!s.isEmpty()){
Stack<BinaryTree> temp = new Stack<>();
while(!s.isEmpty()){
BinaryTree b = s.pop();
System.out.print(b.data+" ");
if(flag){
if(b.left!=null)
temp.push(b.left);
if(b.right!=null)
temp.push(b.right);
}
else{
if(b.right!=null)
temp.push(b.right);
if(b.left!=null)
temp.push(b.left);
}
}
s=temp;
flag=!flag;
}
}
public static ArrayList<LinkedList<BinaryTree>> llForAllNodesAtEachDepth(BinaryTree bt){
ArrayList<LinkedList<BinaryTree>> res = new ArrayList<LinkedList<BinaryTree>>();
return createLlForAllNodesAtEachDepth(res,bt, 0);
}
public static ArrayList<LinkedList<BinaryTree>> createLlForAllNodesAtEachDepth(ArrayList<LinkedList<BinaryTree>> res, BinaryTree bt, int level){
if(bt==null)
return null;
if(level==res.size()){
LinkedList<BinaryTree> list = new LinkedList<BinaryTree>();
list.add(bt);
res.add(list);
createLlForAllNodesAtEachDepth(res,bt.left,level+1);
createLlForAllNodesAtEachDepth(res,bt.right,level+1);
}
else{
res.get(level).add(bt);
createLlForAllNodesAtEachDepth(res,bt.left,level+1);
createLlForAllNodesAtEachDepth(res,bt.right,level+1);
}
return res;
}
public static void zigZagTraversal(ArrayList<LinkedList<BinaryTree>> res){
boolean flag=true;
for(int i=0;i<res.size();i++){
LinkedList<BinaryTree> temp = res.get(i);
if(flag){
for(int j=0;j<temp.size();j++){
System.out.print(temp.get(j).data+" -> ");
}
flag=false;
}
else{
for(int j=temp.size()-1;j>=0;j--){
System.out.print(temp.get(j).data+" -> ");
}
flag=true;
}
System.out.println();
}
}
}
/ / простой код c++ с использованием двух стеков
<pre> void zigzag(struct node *root)
{
int lefttoright = 1 ;
struct node *temp ;
if(root == NULL)
return ;
stack<struct node *> current , next ,temp2 ;// temp is used to swap
////current and next
current.push(root);
while(!current.empty())
{temp = current.top();
current.pop();
cout<< temp->data << " " ;
if(lefttoright)
{ if(temp->left)
next.push(temp->left) ;
if(temp->right)
next.push(temp->right) ;
}
else
{if(temp->right)
next.push(temp->right) ;
if(temp->left)
next.push(temp->left) ;
}
if(current.empty()) // make current as next and next as current
//to hold next level nodes
{lefttoright = 1-lefttoright ;
temp2 = current ;
current = next ;
next = temp2 ;
}
}
</pre>