非递归遍历要用到stack,出栈即访问
前序遍历:(中结点->左结点->右节点)
思路:先将根节点入栈,之后进入循环,先出栈一个结点A, 之后如果存在的话,将A的右结点入栈,再将A的左结点入栈,之后继续循环。。这样一直循环到栈空为止。
中序遍历: (左结点->中结点->右节点)
思路:扫描根节点,将其所有左孩子结点全部入栈, 之后出栈一个结点A,之后再扫描A结点的右孩子结点,进入循环。一直循环到栈空。
后序遍历:(左结点->右结点->中节点)
思路: 跟中序的差不多,只是在出栈的时候多了个条件限制,必须A左右孩子结点都出栈了,A结点才能出栈,此时需要用个结点指针pre来记录上一个访问的结点。
判断条件: A ->right == pre || A->right ==NULL
若A->right =NULL,则可以直接将A出栈,因为他没有右孩子结点了。
层序遍历:(层序遍历要使用队列,先进先出,后进后出。)
思路: 先将根节点入队,之后只要队列不为空就进入循环,循环内先出队头元素A,之后将A的左孩子跟右孩子再入队,这样一直循环到队列为空为止。
(出队即访问结点)
中序遍历与后序遍历代码如下:
#include<stdio.h> #include<malloc.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; int createTree(struct TreeNode **root, int *arr, int *i){ if(arr[*i] == '#'){ *root = NULL; (*i)++; } else{ *root = (struct TreeNode *)malloc(sizeof(struct TreeNode)); (*root)->val = arr[(*i)++]; createTree(&((*root)->left), arr, i); createTree(&((*root)->right), arr, i); } return 1; } int* postorderTraversal(struct TreeNode* root, int* returnSize) { if(root == NULL){ *returnSize = 0; return NULL; } int *retArr = (int *)malloc(sizeof(int) * 1000); int retSize = 0; struct TreeNode *treeArr[1000], *cur = root, *pre; int top = -1; while(top > -1 || cur){ while(cur){ treeArr[++top] = cur; cur = cur->left; } cur = treeArr[top]; if(cur->right == NULL || cur->right == pre){ top--; retArr[retSize++] = cur->val; pre = cur; cur = NULL; }else{ cur = cur->right; } } *returnSize = retSize; return retArr; } int* inorderTraversal(struct TreeNode* root, int* returnSize) { if(root == NULL){ *returnSize = 0; return NULL; } int *retArr = (int *)malloc(sizeof(int) * 1000); int retSize = 0; struct TreeNode *treeArr[1000], *cur = root; int top = -1; while(top > -1 || cur){ while(cur){ treeArr[++top] = cur; cur = cur->left; } if(top > -1){ cur = treeArr[top--]; retArr[retSize++] = cur->val; cur = cur->right; } } *returnSize = retSize; return retArr; } int main(){ int arr[] = { 'A', 'B', 'C', '#', '#', 'D', 'E', '#', 'G', '#', '#', 'F', '#', '#', '#' }; struct TreeNode *root = NULL; int i = 0; createTree(&root, arr, &i); int returnSize, returnSize2; int *retArr = postorderTraversal(root, &returnSize); int *retArr2 = inorderTraversal(root, &returnSize2); for(i = 0; i < returnSize; i++){ printf("%c ",retArr[i]); } printf("\n"); for(i = 0; i < returnSize2; i++){ printf("%c ",retArr2[i]); } printf("\n"); return 0; }