递归实现:

前序遍历

然后对左子树进行先序遍历,再对右子树进行先序遍历,在这些操作之前先将根节点装进容器中

 1 void frontfind(Node* node,  vector<int>& vec) {
 2     if (node == nullptr) {
 3         return;
 4     }
 5     //非终止条件,非递归入口,只需考虑如果只有一个结点需要做什么
 6     vec.push_back(node->data_);
 7     //递归入口的参数是,性质相同但是规模更小的子问题,比如左子树它本身就是一个树但是相对于整个树而言它是一个规模更小的子问题
 8     frontfind(node->left,vec);
 9     frontfind(node->right,vec);
10 }
11 int main() {
12     Node* node1 = new Node(6);
13     Node* node2 = new Node(3);
14     Node* node3 = new Node(9);
15     Node* node4 = new Node(1);
16     Node* node5 = new Node(4);
17     Node* node6 = new Node(8);
18     Node* node7 = new Node(0);
19     node1->left = node2;
20     node1->right = node3;
21     node2->left = node4;
22     node2->right = node5;
23     node3->left = node6;
24     node4->left = node7;
25     vector<int>vec;
26     frontfind(node1, vec);
27     for (auto& v : vec) {
28         cout << v << endl;
29     }
30 }

6310498

中序遍历

对左子树进行先序遍历,再对右子树进行先序遍历,在这些操作之间将根节点装进容器中

 1 void medfind(Node* node,  vector<int>& vec) {
 2     if (node == nullptr) {
 3         return;
 4     }
 5     frontfind(node->left,vec);
 6     vec.push_back(node->data_);
 7     frontfind(node->right,vec);
 8 }
 9 int main() {
10     Node* node1 = new Node(6);
11     Node* node2 = new Node(3);
12     Node* node3 = new Node(9);
13     Node* node4 = new Node(1);
14     Node* node5 = new Node(4);
15     Node* node6 = new Node(8);
16     Node* node7 = new Node(0);
17     node1->left = node2;
18     node1->right = node3;
19     node2->left = node4;
20     node2->right = node5;
21     node3->left = node6;
22     node4->left = node7;
23     vector<int>vec;
24     frontfind(node1, vec);
25     for (auto& v : vec) {
26         cout << v << endl;
27     }
28 }

0134689

后序遍历

对左子树进行先序遍历,然后将根结点输入容器,在这些操作之后将根节点装进容器中

 1 void behindfind(Node* node,  vector<int>& vec) {
 2     if (node == nullptr) {
 3         return;
 4     }
 5     frontfind(node->left,vec);
 6     frontfind(node->right,vec);
 7     vec.push_back(node->data_);
 8 }
 9 int main() {
10     Node* node1 = new Node(6);
11     Node* node2 = new Node(3);
12     Node* node3 = new Node(9);
13     Node* node4 = new Node(1);
14     Node* node5 = new Node(4);
15     Node* node6 = new Node(8);
16     Node* node7 = new Node(0);
17     node1->left = node2;
18     node1->right = node3;
19     node2->left = node4;
20     node2->right = node5;
21     node3->left = node6;
22     node4->left = node7;
23     vector<int>vec;
24     frontfind(node1, vec);
25     for (auto& v : vec) {
26         cout << v << endl;
27     }
28 }

0143896

迭代实现(使用栈)

如果某元素遍历到它立即就要将它装进vector中,我们就要将它压栈之后立即弹栈,如果某元素遍历到它不立即将它装进vector中,我们就要将它压栈之后,再压入其他元素

先序遍历

  • 先将根节点压栈此时根节点为栈顶,然后将栈顶弹栈,如果栈顶的右子树根节点不为空就将它压入栈中,然后左子树根节点不为空就将它压入栈中,然后继续弹栈,继续将栈顶的右子树和左子树压入栈中(如果它们不为空)

 

  • 开头的二叉树使用迭代遍历的思路:

6压栈,6弹栈装入容器,同时将9压栈,然后3压栈,3弹栈装入容器,同时4压栈,然后1压栈,1弹栈装入容器,1的右子树为空,然后让0压栈,0弹栈装入容器,0的右子树为空,0的左子树为空,4弹栈装入容器,4的右子树为空,4的左子树为空,9弹栈装入容器,9的左子树为空,8压栈,8弹栈装入容器,栈为空终止

 

 1 void frontfind(Node* node, vector<int>& vec) {
 2     stack<Node*>st;
    if(node==nullptr) return;
3 st.push(node); 4 Node* temp; 5 while (!st.empty()) { 6 vec.push_back(st.top()->data_); 7 temp = st.top(); 8 st.pop(); 9 if (temp->right) { 10 st.push(temp->right); 11 } 12 if (temp->left) { 13 st.push(temp->left); 14 } 15 } 16 } 17 int main() { 18 Node* node1 = new Node(6); 19 Node* node2 = new Node(3); 20 Node* node3 = new Node(9); 21 Node* node4 = new Node(1); 22 Node* node5 = new Node(4); 23 Node* node6 = new Node(8); 24 Node* node7 = new Node(0); 25 node1->left = node2; 26 node1->right = node3; 27 node2->left = node4; 28 node2->right = node5; 29 node3->left = node6; 30 node4->left = node7; 31 vector<int>vec; 32 frontfind(node1, vec); 33 for (auto& v : vec) { 34 cout << v << endl; 35 } 36 }

后序遍历

在前序遍历基础上更改,改为:先将左子树的根节点压栈,然后再把右子树的根节点压栈,函数的最后发生一次反转

 1 void reverse(vector<int>& vec) {
 2     auto beg = vec.begin(), end = vec.end() - 1;
 3     int temp;
 4     while (beg < end) {
 5         temp = *beg;
 6         *beg++ = *end;
 7         *end-- = temp;
 8     }
 9 }
10 void behindfind(Node* node, vector<int>& vec) {
11     stack<Node*>st;
    if(node==nullptr) return;
12 st.push(node); 13 Node* temp; 14 while (!st.empty()) { 15 vec.push_back(st.top()->data_); 16 temp = st.top(); 17 st.pop(); 18 if (temp->left) { 19 st.push(temp->left); 20 } 21 if (temp->right) { 22 st.push(temp->right); 23 } 24 } 25 reverse(vec); 26 } 27 28 int main() { 29 Node* node1 = new Node(6); 30 Node* node2 = new Node(3); 31 Node* node3 = new Node(9); 32 Node* node4 = new Node(1); 33 Node* node5 = new Node(4); 34 Node* node6 = new Node(8); 35 Node* node7 = new Node(0); 36 node1->left = node2; 37 node1->right = node3; 38 node2->left = node4; 39 node2->right = node5; 40 node3->left = node6; 41 node4->left = node7; 42 vector<int>vec; 43 frontfind(node1, vec); 44 for (auto& v : vec) { 45 cout << v << endl; 46 } 47 }

中序遍历

定义一个temp用来记录当前结点

遍历到的结点不为空就将它压栈,然后将temp->left给temp

否则

当前结点为空的时候将stack.top给temp,并将stack.top装入vector容器,然后弹栈,然后将temp->right给temp

 

总的来说:浏览到的结点不为空就把该节点压栈,然后浏览该节点左侧,如果为空就将栈顶弹出,然后浏览栈顶的右侧

 1 void medfind(Node* node, vector<int>& vec) {
 2     stack<Node*>st;
    if(node==nullptr) return;
3 Node* temp = node; 4 //只有temp为空的情况下采取判断st是否为空 5 while ((temp!=nullptr)||(!st.empty())) { 6 if (temp) { 7 st.push(temp); 8 temp = temp->left; 9 } 10 else { 11 temp = st.top(); 12 st.pop(); 13 vec.push_back(temp->data_); 14 temp = temp->right; 15 } 16 } 17 } 18 19 int main() { 20 Node* node1 = new Node(6); 21 Node* node2 = new Node(3); 22 Node* node3 = new Node(9); 23 Node* node4 = new Node(1); 24 Node* node5 = new Node(4); 25 Node* node6 = new Node(8); 26 Node* node7 = new Node(0); 27 node1->left = node2; 28 node1->right = node3; 29 node2->left = node4; 30 node2->right = node5; 31 node3->left = node6; 32 node4->left = node7; 33 vector<int>vec; 34 medfind(node1, vec); 35 for (auto& v : vec) { 36 cout << v << endl; 37 } 38 }

层序遍历

假定一层的结点数为n,每个for循环都执行n次“出队,并将左子树的根节点入队,将右子树的根节点入队”的过程

 1 void ceng(Node* node, vector<vector<int>>& result) {
 2     queue<Node*>qu;
 3     qu.push(node); 
4
int size = 0; 5 //只有temp为空的情况下采取判断st是否为空 6 while (!qu.empty()) { 7 size = qu.size();//for循环中处理完这一层后,它的下一层的数据就全都在队列中装好了,因此在处理完下一层之前先求队列的尺寸,以此来确定下一次for循环该执行几次 9 vector<int>vec; 10 for (int i = 0; i < size; i++) {
12 vec.push_back(qu.front()->data_); 13 qu.pop(); 14 if (qu.front()->left) { 15 qu.push(temp->left); 16 } 17 if (qu.front()->right) { 18 qu.push(temp->right); 19 } 20 } 21 result.push_back(vec); 22 } 23 } 24 25 int main() { 26 Node* node1 = new Node(6); 27 Node* node2 = new Node(3); 28 Node* node3 = new Node(9); 29 Node* node4 = new Node(1); 30 Node* node5 = new Node(4); 31 Node* node6 = new Node(8); 32 Node* node7 = new Node(0); 33 node1->left = node2; 34 node1->right = node3; 35 node2->left = node4; 36 node2->right = node5; 37 node3->left = node6; 38 node4->left = node7; 39 vector<vector<int>>result; 40 ceng(node1, result); 41 for (auto& v : result) { 42 for (auto& in : v) { 43 cout << in << endl; 44 } 45 } 46 }

 

posted on 2023-08-02 15:01  小凉拖  阅读(10)  评论(0编辑  收藏  举报