前期准备知识html
二叉树基本知识:数据结构与算法——数据结构知识概括node
又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也能够从右往左)访问结点,访问完一层就进入下一层,直到没有结点能够访问为止。
遍历规则:算法
遍历结果:数据结构
root->A->B->C->D->Epost
程序实现:.net
/*二叉树结构*/ struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} };
/*广度优先*/ void breadthFirstSearch(TreeNode* root){ queue<TreeNode*> nodeQueue; //使用队列 nodeQueue.push(root); TreeNode* node; while(!nodeQueue.empty()){ node = nodeQueue.front(); nodeQueue.pop(); printf(format, node->val); if(node->left){ nodeQueue.push(node->left); //先将左子树入队 } if(node->right){ nodeQueue.push(node->right); //再将右子树入队 } } }
对每个可能的分支路径深刻到不能再深刻为止,并且每一个结点只能访问一次。要特别注意的是,二叉树的深度能够细分为先序遍历、中序遍历、后序遍历。code
遍历规则:orm
不断地沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。htm
遍历结果:blog
先序:root->A->C->D->B->E
中序:C->A->D->root->B->E
后序:C->D->A->E->B->root
程序实现:
/*二叉树结构*/ struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} };
(1)先序遍历
/*递归*/ void preOrderTraverse(TreeNode*root) { printf(format,root->val); if (root->left) preOrderTraverse(root->left); if (root->right) preOrderTraverse(root->right); } /*非递归*/ void preOrderTraverse(TreeNode* root){ stack<TreeNode*> nodeStack; //使用栈 nodeStack.push(root); TreeNode* node; while(!nodeStack.empty()){ node = nodeStack.top(); printf(format, node->val); nodeStack.pop(); if(node->right){ nodeStack.push(node->right); //先将右子树压栈 } if(node->left){ nodeStack.push(node->left); //再将左子树压栈 } } }
(2)中序遍历
/*递归*/ void inOrderTraverse(TreeNode* root) { if (root->left) inOrderTraverse(root->left); printf(format,root->val); if (root->right) inOrderTraverse(root->right); } /*非递归*/ void inOrderTraverse(TreeNode* root){ stack<TreeNode*> nodeStack; //使用栈 TreeNode* currentNode = root; while (currentNode || !nodeStack.empty()){ if (currentNode) { nodeStack.push(currentNode); currentNode = currentNode->left; } else { currentNode = nodeStack.top(); nodeStack.pop(); printf(format,root->val); currentNode = currentNode->right; } } }
(3)后序遍历
/*递归*/ void postOrderTraverse(TreeNode* root) { if (root->left) postOrderTraverse(root->left); if (root->right) postOrderTraverse(root->right); printf(format,root->val); } /*非递归*/ void postOrderTraverse(TreeNode* root) { stack<TreeNode*node>nodeStack; //使用栈 TreeNode* currentNode = root; TreeNode* rightNode = null; while (currentNode|| !stack.empty()) { // 一直循环到二叉排序树最左端的叶子结点 while (currentNode) { nodeStack.push(currentNode); currentNode = currentNode->left; } currentNode = stack.top(); stack.pop(); // 当前结点没有右结点或上一个结点(已经输出的结点)是当前结点的右结点,则输出当前结点 while (currentNode.right == null || currentNode.right == rightNode) { printf(format,root->val); rightNode = currentNode; if (stack.isEmpty()) { return; //root以输出,则遍历结束 } currentNode = stack.top(); stack.pop(); } stack.push(currentNode); //还有右结点没有遍历 currentNode = currentNode->right; } }
参考