这不是家庭作业。我正在考虑树遍历中的一些新问题,这似乎非常明显,所以想到解决它。
问题与BFS等级别顺序遍历非常相似。在BFS中,我们通常在树的每个级别从左到右行进,但是如果我们在级别i从左到右行进,那么级别(i-1)和(i + 1)需要从右到左行进。
例如:
2
/ \
7 5
/ \ \
2 6 9
/ \ \
5 11 4
在正常的BFS中,我们输出:2,7,5,2,6,9,5,11,4
但我正在寻找一个解决方案,我们输出:2,5,7,2,6,9,4,11,5
我能够找到解决方案。但是,我想看看是否有人提出了更好的解决方案。我特别关注空间复杂度(堆栈大小)的优化。
请根据C ++语言提供您的逻辑。如果您在解决方案中不使用任何容器或STL,我将不胜感激。
根据这里的评论,我提出了一个使用两个堆栈的解决方案。我的解决方案如下。
/*
Create Stack S1, S2; // for tmp itr. Both of size log<n>
Create Queue Q; // It will hold ans
*/
Q.enqueue(root); //Enqueue the root nood;
S1.enqueue(root); //Fill the stack with somthing to start.
while(S1||S2){ // keep spinning untill both stack are empty.
while(s1){ //take care of stack S1.
Node* tmp = S1.pop(); //take top elem;
if(tmp->right){
Q.enqueue(tmp->right);
S2.push(tmp->right);
}
if(tmp->left){
Q.enqueue(tmp->left);
S2.push(tmp->left);
}
}
while(S2){ //while S2 is not empty
Node* tmp = S2.pop();
if(tmp->left){
Q.enqueue(tmp->left);
S1.push(tmp->left);
}
if(tmp->right){
Q.enqueue(tmp->right);
S1.push(tmp->right);
}
}
} //End of outher while
while(Q){
cout<< Q.pop()->data; //output the entries in desired format.
}
对我来说似乎没关系(如果不是,请告诉我)。但仍然想知道是否可以有任何其他解决方案(比这更好)。
答案 0 :(得分:2)
不使用单个队列,而是使用一对堆栈。当前堆栈为空时,开始从另一个节点弹出节点,并将他们的孩子推到现在空的节点上。
所以你有
等
你需要一个状态变量来决定是先向左还是向右推。
答案 1 :(得分:1)
我刚刚尝试了Potatoswatter在C#中给出的上述建议。我没有尝试过运行它。如果需要修改某些内容,请纠正我。
void BFSTraversePrintzigzag(Node root)
{
bool bLeftToRight = true;
Stack<Node> stack1=new Stack<Node>();
Stack<Node> stack2=new Stack<Node>();
stack1.Push(root);
//loop until both the stacks are empty
while(stack1.Count>0 ||stack2.Count>0)
{
//Stack1 will be empty when all the nodes on a level are traversed.
if (stack1.Count==0 && stack2.Count>0)
{
//Swap stack1 and stack2, if stack1 is empty
stack1= stack2;
while(stack2.Count>0)
stack2.Pop();
bLeftToRight=!bLeftToRight;
//This is the state variable to switch the order from left to right and from Right to left
}
root=stack1.Pop();
Console.WriteLine(root.data) ;
if(bLeftToRight)
{
if(root.left!=null)
stack2.Push(root.left);
if(root.right!=null)
stack2.Push(root.right);
}
else
{
if(root.right!=null)
stack2.Push(root.right);
if(root.left!=null)
stack2.Push(root.left);
}
}
}
答案 2 :(得分:0)
如果我理解你想要什么,我会使用优先级队列而不是堆栈。作为优先级队列的密钥,您需要将级别存储在节点的树中以及该级别中的顺序。比较函数将使用级别作为主键。对于偶数级别,它将直接使用订单作为辅助密钥,但对于奇数级别,它将否定它。根据您是否考虑树级别0或级别1的根,您可能需要反转哪些级别直接使用而不是否定。