【数据结构与算法】二叉树的遍历

让人想犯罪 __ 提交于 2020-01-28 09:52:48

前序遍历是指,对于树中的任意节点来说,先打印这个节点,然后再打印它的左子树,最后打印它的右子树。

中序遍历是指,对于树中的任意节点来说,先打印它的左子树,然后再打印它本身,最后打印它的右子树。

后序遍历是指,对于树中的任意节点来说,先打印它的左子树,然后再打印它的右子树,最后打印这个节点本身。

层次遍历是指,对树中的节点一层一层的打印,其实就是广度优先算法(BFS)。

一、前序遍历

LeetCode: https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

C语言代码实现:

  1 /**
  2  * Definition for a binary tree node.
  3  * struct TreeNode {
  4  *     int val;
  5  *     struct TreeNode *left;
  6  *     struct TreeNode *right;
  7  * };
  8  */
  9 
 10 
 11 /**
 12  * Note: The returned array must be malloced, assume caller calls free().
 13  */
 14 
 15 /* 获取树的节点个数 */
 16 int getTreeNodeLen(struct TreeNode* root)
 17 {
 18     if (root == NULL) {
 19         return 0;
 20     }
 21     return 1 + getTreeNodeLen(root->left) + getTreeNodeLen(root->right);
 22 }
 23 
 24 /* 树的前序遍历: 递归 */
 25 void preorder(struct TreeNode *root, int *returnSize, int *result)
 26 {
 27     if (root == NULL) {
 28         return;
 29     }
 30     result[*returnSize] = root->val;
 31     (*returnSize)++;
 32     preorder(root->left, returnSize, result);
 33     preorder(root->right, returnSize, result);
 34     return;
 35 }
 36 
 37 int* preorderTraversal(struct TreeNode *root, int *returnSize){
 38     (*returnSize) = 0;
 39     int len = getTreeNodeLen(root);
 40     if (len == 0) {
 41         return NULL;
 42     }
 43     
 44     int *result = (int *)malloc(len * sizeof(int));
 45     if (result == NULL) {
 46         return NULL;
 47     }
 48     /************* 递归实现 **************/
 49     //preorder(root, returnSize, result);
 50     
 51     
 52     /**********  非递归实现的第一种方法 ************************/
 53     /*
 54     struct TreeNode **stacks = (struct TreeNode **)malloc(len * sizeof(struct TreeNode *));
 55     if (stacks == NULL) {
 56         return NULL;
 57     }
 58     int top = -1; 
 59     stacks[++top] = root;
 60     struct TreeNode *tmp = NULL;
 61     //int i = 0;
 62     while (top != -1) {
 63         tmp = stacks[top--];
 64         result[*returnSize] = tmp->val;
 65         // printf("result:%d ", tmp->val);
 66         (*returnSize)++;
 67         
 68         if (tmp->right) {
 69             stacks[++top] = tmp->right;
 70             // printf("right:%d\n", tmp->right->val);
 71         }  
 72         if (tmp->left) {
 73             stacks[++top] = tmp->left;
 74             // printf("left:%d ", tmp->left->val);
 75         }
 76 
 77     }
 78     free(stacks);
 79     stacks = NULL;
 80     */
 81     
 82     /******** 非递归实现的第二种方法  **********/
 83     struct TreeNode **stacks = (struct TreeNode **)malloc(len * sizeof(struct TreeNode *));
 84     if (stacks == NULL) {
 85         return NULL;
 86     }
 87     int top = -1; 
 88     struct TreeNode *tmp = root;
 89     int i = 0;
 90     while (tmp != NULL || top != -1) {
 91         if (tmp != NULL) {
 92             result[i++] = tmp->val;
 93             stacks[++top] = tmp;
 94             tmp = tmp->left;
 95         } else {
 96             tmp =  stacks[top--];
 97             tmp = tmp->right;
 98         }
 99     }
100     free(stacks);
101     stacks = NULL;
102     (*returnSize) = i;
103     return result;
104 }
View Code

 

二、中序遍历

LeetCode:  https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

C语言代码实现:

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     struct TreeNode *left;
 6  *     struct TreeNode *right;
 7  * };
 8  */
 9 
10 
11 /**
12  * Note: The returned array must be malloced, assume caller calls free().
13  */
14 
15 int getTreeNodeLen(struct TreeNode* root)
16 {
17     if (root == NULL) {
18         return 0;
19     }
20     return 1 + getTreeNodeLen(root->left) + getTreeNodeLen(root->right);
21 }
22 
23 void inorder(struct TreeNode* root, int* returnSize, int *result)
24 {
25     if (root == NULL) {
26         return;
27     }
28     inorder(root->left, returnSize, result);
29     result[*returnSize] = root->val;
30     (*returnSize)++;
31     inorder(root->right, returnSize, result);
32     return;
33 }
34 
35 int* inorderTraversal(struct TreeNode* root, int* returnSize){
36     int len = getTreeNodeLen(root);
37     (*returnSize) = 0;
38     if (len == 0) {
39         return NULL;
40     }
41     
42     int *result = (int *)malloc(len * sizeof(int));
43     if (result == NULL) {
44         return NULL;
45     }
46     /* 方法一: 递归 */
47     //inorder(root, returnSize, result);
48     
49     /* 方法二: 非递归 */
50     struct TreeNode **stacks = (struct TreeNode**)malloc(len * sizeof(struct TreeNode *));
51     if (stacks == NULL) {
52         return NULL;
53     }
54     int top = -1;
55     struct TreeNode* tmp = root;
56     int i = 0;
57     while (tmp != NULL || top != -1) {
58         if (tmp) {
59             stacks[++top] = tmp;
60             tmp = tmp->left;
61         } else {
62             tmp = stacks[top--];
63             result[i++] = tmp->val;
64             tmp = tmp->right;
65         }
66     }
67     (*returnSize) = i;
68     free(stacks);
69     stacks = NULL;
70     
71     return result;
72 }
View Code

 

三、后序遍历

LeetCode: https://leetcode-cn.com/problems/binary-tree-postorder-traversal/submissions/

C语言代码实现:

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     struct TreeNode *left;
 6  *     struct TreeNode *right;
 7  * };
 8  */
 9 
10 
11 /**
12  * Note: The returned array must be malloced, assume caller calls free().
13  */
14 
15 int getTreeNodeLen(struct TreeNode* root)
16 {
17     if (root == NULL) {
18         return 0;
19     }
20     return 1 + getTreeNodeLen(root->left) + getTreeNodeLen(root->right);
21 }
22 
23 void postOrder(struct TreeNode* root, int* returnSize, int *result)
24 {
25     if (root == NULL) {
26         return;
27     }
28     postOrder(root->left, returnSize, result);
29     postOrder(root->right, returnSize, result);
30     result[*returnSize] = root->val;
31     (*returnSize)++;
32     return;
33 }
34 
35 int* postorderTraversal(struct TreeNode* root, int* returnSize){
36     int len = getTreeNodeLen(root);
37     (*returnSize) = 0;
38     if (len == 0) {
39         return NULL;
40     }
41     
42     int *result = (int *)malloc(len * sizeof(int));
43     if (result == NULL) {
44         return NULL;
45     }
46     
47     /* 递归实现 */
48     //postOrder(root, returnSize, result);
49     
50     // 非递归实现 
51     struct TreeNode **stacks = (struct TreeNode **)malloc(len * sizeof(struct TreeNode *));
52     if (stacks == NULL) {
53         return NULL;
54     }
55     int top = -1;
56     struct TreeNode * tmp = root;
57     int i = 0;
58     struct TreeNode * prev = NULL;
59     struct TreeNode * topNode = NULL;
60     while (tmp != NULL || top != -1) {
61         // 先把所有的左孩子入栈,到叶子节点为止
62         if (tmp) {
63             stacks[++top] = tmp;
64             //printf("left: tmp:%d\n", tmp->val);
65             tmp = tmp->left;
66         } else {
67             topNode = stacks[top];
68             //printf("topNode: %d\n", topNode->val);
69             if (topNode->right == NULL || prev == topNode->right) { /* 如果右孩子为空,或者上一次遍历的是右孩子。直接将该节点输出 */
70                 result[i++] = topNode->val;
71                 prev = topNode;
72                 top--;
73             } else { /* 有右孩子并且还没访问,将当前节点置为右孩子 */
74                 tmp = topNode->right;
75             }
76         }
77     }
78     //printf("i:%d\n", i);
79     (*returnSize) = i;
80     return result;
81 }
View Code

 

四、层次遍历

LeetCode: https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

C语言代码实现:

  1 /**
  2  * Definition for a binary tree node.
  3  * struct TreeNode {
  4  *     int val;
  5  *     struct TreeNode *left;
  6  *     struct TreeNode *right;
  7  * };
  8  */
  9 
 10 
 11 /**
 12  * Return an array of arrays of size *returnSize.
 13  * The sizes of the arrays are returned as *returnColumnSizes array.
 14  * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 15  */
 16 
 17 int getTreeNodeLen(struct TreeNode* root)
 18 {
 19     if (root == NULL) {
 20         return 0;
 21     }
 22     return 1 + getTreeNodeLen(root->left) + getTreeNodeLen(root->right);
 23 }
 24 
 25 void helper(struct TreeNode* root, int** result, int* ColumnSizes, int i, int* maxh) {
 26     if (root != NULL) {
 27         result[i][ColumnSizes[i]] = root->val;
 28         ColumnSizes[i]++;
 29         if(i+1>*maxh)
 30             *maxh = i+1;
 31         helper(root->left, result, ColumnSizes, i + 1, maxh);
 32         helper(root->right, result, ColumnSizes, i + 1, maxh);
 33     }
 34 }
 35 
 36 int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
 37     (*returnSize) = 0;
 38     int len = getTreeNodeLen(root);
 39     if (len == 0) {
 40         return NULL;
 41     }
 42     int **result = (int **)malloc(sizeof(int *) * len);
 43     for (int i = 0; i < len; i++) {
 44         result[i] = (int *)malloc(len * sizeof(int));
 45     }
 46     *returnColumnSizes = (int*)calloc(len, sizeof(int));
 47     // 递归实现
 48     helper(root, result, *returnColumnSizes, 0, returnSize);
 49     return result;
 50     
 51     
 52     // 非递归实现
 53     /*
 54     (*returnSize) = 0;
 55     int len = getTreeNodeLen(root);
 56     if (len == 0) {
 57         return NULL;
 58     }
 59     (*returnColumnSizes) = (int *)malloc(len * sizeof(int));
 60     int **result = (int **)malloc(len * sizeof(int *));
 61     if (result == NULL) {
 62         return NULL;
 63     }
 64     
 65     struct TreeNode **queue = (struct TreeNode **)malloc(len * sizeof(struct TreeNode *));
 66     if (queue == NULL) {
 67         return NULL;
 68     }
 69     
 70     
 71     int front = 0;
 72     int back = 0;
 73     int i;
 74     struct TreeNode * tmp = NULL;
 75     
 76     queue[back++] = root;
 77     result[0] = (int*)malloc(sizeof(int));
 78     result[0][0] = root->val;
 79     (*returnColumnSizes)[0] = 1;
 80     i = 1;
 81     while (front != back) {
 82         tmp = queue[front];
 83         printf("entry: front:%d, back:%d\n", front, back);
 84         printf("queue: %d\n", tmp->val);
 85         if (tmp->left && tmp->right) {
 86             result[i] = (int*)malloc(2 * sizeof(int));
 87             result[i][0] = tmp->left->val;
 88             result[i][1] = tmp->right->val;
 89             printf("both: result[%d][0]:%d,  result[%d][1]:%d\n", i, result[i][0], i, result[i][1]);
 90             queue[back++] = tmp->left;
 91             queue[back++] = tmp->right;
 92             (*returnColumnSizes)[i] = 2;
 93             i++;
 94             printf("front:%d, back:%d\n", front, back);
 95         } else if (tmp->left) {
 96             result[i] = (int *)malloc(sizeof(int));
 97             result[i][0] = tmp->left->val;
 98             printf("left: result[%d][0]:%d\n", i, result[i][0]);
 99             queue[back++] = tmp->left;
100             (*returnColumnSizes)[i] = 1;
101             i++;
102             printf("left: front:%d, back:%d\n", front, back);
103         } else if (tmp->right) {
104             result[i] = (int *)malloc(sizeof(int));
105             result[i][0] = tmp->right->val;
106             printf("right: result[%d][0]:%d\n", i, result[i][0]);
107             queue[back++] = tmp->right;
108             (*returnColumnSizes)[i] = 1;
109             i++;
110             printf("right: front:%d, back:%d\n", front, back);
111         }
112         front++;
113         printf("\n\n");
114     }
115     (*returnSize) = i;
116     // printf("returnSize :%d\n", (*returnSize));
117     free(queue);
118     queue = NULL;
119     return result;
120     */
121 }
View Code
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!