先决条件 – 树的中序/前序/后序遍历
给定一棵二叉树,执行后序遍历。
我们已经讨论了下面的后序遍历方法。
1) 递归后序遍历。
2) 使用堆栈的后序遍历。
2) 使用两个堆栈的后序遍历。
在该方法中,讨论了基于 DFS 的解决方案。我们在哈希表中跟踪访问过的节点。
C++
// CPP program or postorder traversal
#include
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct Node {
int data;
struct Node *left, *right;
};
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
void postorder(struct Node* head)
{
struct Node* temp = head;
unordered_set visited;
while (temp && visited.find(temp) == visited.end()) {
// Visited left subtree
if (temp->left &&
visited.find(temp->left) == visited.end())
temp = temp->left;
// Visited right subtree
else if (temp->right &&
visited.find(temp->right) == visited.end())
temp = temp->right;
// Print node
else {
printf("%d ", temp->data);
visited.insert(temp);
temp = head;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
Java
// JAVA program or postorder traversal
import java.util.*;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class Node
{
int data;
Node left, right;
Node(int data)
{
this.data = data;
this.left = this.right = null;
}
};
class GFG
{
Node root;
/* Helper function that allocates a new node with the
given data and null left and right pointers. */
void postorder(Node head)
{
Node temp = root;
HashSet visited = new HashSet<>();
while ((temp != null && !visited.contains(temp)))
{
// Visited left subtree
if (temp.left != null &&
!visited.contains(temp.left))
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
!visited.contains(temp.right))
temp = temp.right;
// Print node
else
{
System.out.printf("%d ", temp.data);
visited.add(temp);
temp = head;
}
}
}
/* Driver program to test above functions*/
public static void main(String[] args)
{
GFG gfg = new GFG();
gfg.root = new Node(8);
gfg.root.left = new Node(3);
gfg.root.right = new Node(10);
gfg.root.left.left = new Node(1);
gfg.root.left.right = new Node(6);
gfg.root.left.right.left = new Node(4);
gfg.root.left.right.right = new Node(7);
gfg.root.right.right = new Node(14);
gfg.root.right.right.left = new Node(13);
gfg.postorder(gfg.root);
}
}
// This code is contributed by Rajput-Ji
Python
# Python program or postorder traversal
''' A binary tree node has data, pointer to left child
and a pointer to right child '''
class newNode:
# Constructor to create a newNode
def __init__(self, data):
self.data = data
self.left = None
self.right = None
''' Helper function that allocates a new node with the
given data and NULL left and right pointers. '''
def postorder(head):
temp = head
visited = set()
while (temp and temp not in visited):
# Visited left subtree
if (temp.left and temp.left not in visited):
temp = temp.left
# Visited right subtree
elif (temp.right and temp.right not in visited):
temp = temp.right
# Print node
else:
print(temp.data, end = " ")
visited.add(temp)
temp = head
''' Driver program to test above functions'''
if __name__ == '__main__':
root = newNode(8)
root.left = newNode(3)
root.right = newNode(10)
root.left.left = newNode(1)
root.left.right = newNode(6)
root.left.right.left = newNode(4)
root.left.right.right = newNode(7)
root.right.right = newNode(14)
root.right.right.left = newNode(13)
postorder(root)
# This code is contributed by
# SHUBHAMSINGH10
C#
// C# program or postorder traversal
using System;
using System.Collections.Generic;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
public
class Node
{
public
int data;
public
Node left, right;
public
Node(int data)
{
this.data = data;
this.left = this.right = null;
}
};
class GFG
{
Node root;
/* Helper function that allocates a new node with the
given data and null left and right pointers. */
void postorder(Node head)
{
Node temp = root;
HashSet visited = new HashSet();
while ((temp != null && !visited.Contains(temp)))
{
// Visited left subtree
if (temp.left != null &&
!visited.Contains(temp.left))
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
!visited.Contains(temp.right))
temp = temp.right;
// Print node
else
{
Console.Write(temp.data + " ");
visited.Add(temp);
temp = head;
}
}
}
/* Driver code*/
public static void Main(String[] args)
{
GFG gfg = new GFG();
gfg.root = new Node(8);
gfg.root.left = new Node(3);
gfg.root.right = new Node(10);
gfg.root.left.left = new Node(1);
gfg.root.left.right = new Node(6);
gfg.root.left.right.left = new Node(4);
gfg.root.left.right.right = new Node(7);
gfg.root.right.right = new Node(14);
gfg.root.right.right.left = new Node(13);
gfg.postorder(gfg.root);
}
}
// This code is contributed by Rajput-Ji
Javascript
C++
// CPP program or postorder traversal
#include
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct Node {
int data;
struct Node *left, *right;
bool visited;
};
void postorder(struct Node* head)
{
struct Node* temp = head;
while (temp && temp->visited == false) {
// Visited left subtree
if (temp->left && temp->left->visited == false)
temp = temp->left;
// Visited right subtree
else if (temp->right && temp->right->visited == false)
temp = temp->right;
// Print node
else {
printf("%d ", temp->data);
temp->visited = true;
temp = head;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
node->visited = false;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
Java
// Java program or postorder traversal
class GFG
{
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
static class Node
{
int data;
Node left, right;
boolean visited;
}
static void postorder( Node head)
{
Node temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
System.out.printf("%d ", temp.data);
temp.visited = true;
temp = head;
}
}
}
static Node newNode(int data)
{
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
/* Driver code*/
public static void main(String []args)
{
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
// This code is contributed by Arnab Kundu
Python3
"""Python3 program or postorder traversal """
# A Binary Tree Node
# Utility function to create a
# new tree node
class newNode:
# Constructor to create a newNode
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.visited = False
def postorder(head) :
temp = head
while (temp and temp.visited == False):
# Visited left subtree
if (temp.left and
temp.left.visited == False):
temp = temp.left
# Visited right subtree
elif (temp.right and
temp.right.visited == False):
temp = temp.right
# Print node
else:
print(temp.data, end = " ")
temp.visited = True
temp = head
# Driver Code
if __name__ == '__main__':
root = newNode(8)
root.left = newNode(3)
root.right = newNode(10)
root.left.left = newNode(1)
root.left.right = newNode(6)
root.left.right.left = newNode(4)
root.left.right.right = newNode(7)
root.right.right = newNode(14)
root.right.right.left = newNode(13)
postorder(root)
# This code is contributed by
# SHUBHAMSINGH10
C#
// C# program or postorder traversal
using System;
class GFG
{
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
class Node
{
public int data;
public Node left, right;
public bool visited;
}
static void postorder( Node head)
{
Node temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
Console.Write("{0} ", temp.data);
temp.visited = true;
temp = head;
}
}
}
static Node newNode(int data)
{
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
/* Driver code*/
public static void Main(String []args)
{
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
// This code is contributed by 29AjayKumar
Javascript
C++
// CPP program or postorder traversal
#include
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct Node {
int data;
struct Node *left, *right;
bool visited;
};
void postorder(Node* root)
{
Node* n = root;
unordered_map parentMap;
parentMap.insert(pair(root, nullptr));
while (n) {
if (n->left && parentMap.find(n->left) == parentMap.end()) {
parentMap.insert(pair(n->left, n));
n = n->left;
}
else if (n->right && parentMap.find(n->right) == parentMap.end()) {
parentMap.insert(pair(n->right, n));
n = n->right;
}
else {
cout << n->data << " ";
n = (parentMap.find(n))->second;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
node->visited = false;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
输出:
1 4 7 6 3 13 14 10 8
替代解决方案:
我们可以为每个节点保留访问标志,而不是单独的哈希表。
C++
// CPP program or postorder traversal
#include
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct Node {
int data;
struct Node *left, *right;
bool visited;
};
void postorder(struct Node* head)
{
struct Node* temp = head;
while (temp && temp->visited == false) {
// Visited left subtree
if (temp->left && temp->left->visited == false)
temp = temp->left;
// Visited right subtree
else if (temp->right && temp->right->visited == false)
temp = temp->right;
// Print node
else {
printf("%d ", temp->data);
temp->visited = true;
temp = head;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
node->visited = false;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
Java
// Java program or postorder traversal
class GFG
{
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
static class Node
{
int data;
Node left, right;
boolean visited;
}
static void postorder( Node head)
{
Node temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
System.out.printf("%d ", temp.data);
temp.visited = true;
temp = head;
}
}
}
static Node newNode(int data)
{
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
/* Driver code*/
public static void main(String []args)
{
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
// This code is contributed by Arnab Kundu
蟒蛇3
"""Python3 program or postorder traversal """
# A Binary Tree Node
# Utility function to create a
# new tree node
class newNode:
# Constructor to create a newNode
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.visited = False
def postorder(head) :
temp = head
while (temp and temp.visited == False):
# Visited left subtree
if (temp.left and
temp.left.visited == False):
temp = temp.left
# Visited right subtree
elif (temp.right and
temp.right.visited == False):
temp = temp.right
# Print node
else:
print(temp.data, end = " ")
temp.visited = True
temp = head
# Driver Code
if __name__ == '__main__':
root = newNode(8)
root.left = newNode(3)
root.right = newNode(10)
root.left.left = newNode(1)
root.left.right = newNode(6)
root.left.right.left = newNode(4)
root.left.right.right = newNode(7)
root.right.right = newNode(14)
root.right.right.left = newNode(13)
postorder(root)
# This code is contributed by
# SHUBHAMSINGH10
C#
// C# program or postorder traversal
using System;
class GFG
{
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
class Node
{
public int data;
public Node left, right;
public bool visited;
}
static void postorder( Node head)
{
Node temp = head;
while (temp != null &&
temp.visited == false)
{
// Visited left subtree
if (temp.left != null &&
temp.left.visited == false)
temp = temp.left;
// Visited right subtree
else if (temp.right != null &&
temp.right.visited == false)
temp = temp.right;
// Print node
else
{
Console.Write("{0} ", temp.data);
temp.visited = true;
temp = head;
}
}
}
static Node newNode(int data)
{
Node node = new Node();
node.data = data;
node.left = null;
node.right = null;
node.visited = false;
return (node);
}
/* Driver code*/
public static void Main(String []args)
{
Node root = newNode(8);
root.left = newNode(3);
root.right = newNode(10);
root.left.left = newNode(1);
root.left.right = newNode(6);
root.left.right.left = newNode(4);
root.left.right.right = newNode(7);
root.right.right = newNode(14);
root.right.right.left = newNode(13);
postorder(root);
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
1 4 7 6 3 13 14 10 8
上述解决方案的时间复杂度为 O(n 2 ),在最坏的情况下,我们在访问每个节点后将指针移回头部。
使用 unordered_map 的替代解决方案,其中我们不必将指针移回头部,因此时间复杂度为 O(n)。
C++
// CPP program or postorder traversal
#include
using namespace std;
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct Node {
int data;
struct Node *left, *right;
bool visited;
};
void postorder(Node* root)
{
Node* n = root;
unordered_map parentMap;
parentMap.insert(pair(root, nullptr));
while (n) {
if (n->left && parentMap.find(n->left) == parentMap.end()) {
parentMap.insert(pair(n->left, n));
n = n->left;
}
else if (n->right && parentMap.find(n->right) == parentMap.end()) {
parentMap.insert(pair(n->right, n));
n = n->right;
}
else {
cout << n->data << " ";
n = (parentMap.find(n))->second;
}
}
}
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = NULL;
node->right = NULL;
node->visited = false;
return (node);
}
/* Driver program to test above functions*/
int main()
{
struct Node* root = newNode(8);
root->left = newNode(3);
root->right = newNode(10);
root->left->left = newNode(1);
root->left->right = newNode(6);
root->left->right->left = newNode(4);
root->left->right->right = newNode(7);
root->right->right = newNode(14);
root->right->right->left = newNode(13);
postorder(root);
return 0;
}
输出:
1 4 7 6 3 13 14 10 8
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。