树的建立 遍历
?
二叉樹是采用遞歸定義的,實現起來代碼簡潔(也許并不簡單)。并且它在具體的計算機科學中有很重要的運用,是一種很重要的數據結構,二叉樹有三種遍歷和建立的方式。今天先學習一下它的建立和打印。
建立:
#include<cstdio> #include<iostream> #include<string> #include<vector> #include<algorithm> using namespace std;typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild; }BiTNode,*BiTree;BiTree CreateBiTree(){char ch;BiTree T;scanf("%c",&ch);if(ch=='#')T=NULL;else{T = (BiTree)malloc(sizeof(BiTNode));T->data = ch;T->lchild = CreateBiTree();T->rchild = CreateBiTree(); }
二叉樹遍歷算法
1. 前序/中序/后序遍歷(遞歸實現)
// 前序遍歷 void BT_PreOrder(BiTreePtr pNode) {if (!pNode) return;visit(pNode);BT_PreOrder(pNode->left);BT_PreOrder(pNode->right); } // 中序遍歷 void BT_PreOrder(BiTreePtr pNode) {if (!pNode) return;BT_PreOrder(pNode->left);visit(pNode);BT_PreOrder(pNode->right); } // 后序遍歷 void BT_PreOrder(BiTreePtr pNode) {if (!pNode) return;BT_PreOrder(pNode->left);BT_PreOrder(pNode->right);visit(pNode); }2. 前序遍歷(非遞歸實現)
// 用棧實現 void BT_PreOrderNoRec1(BiTreePtr pNode) {stack<BiTreePtr> s;while (!pNode || !s.empty()){if (!pNode){visit(pNode);s.push(pNode);pNode = pNode->left;}else{pNode = s.pop();pNode = pNode->right;}} }// 用棧實現 void BT_PreOrderNoRec2(BiTreePtr pNode) {if (!pNode){stack<BiTreePtr> s;s.push(pNode);while (!s.empty()){BiTreePtr pvNode = s.pop();visit(pvNode);s.push(pvNode->right);s.push(pvNode->left);}} }// 不用棧實現 每個節點含父節點指針和isVisited【默認為false】狀態變量 且該二叉樹含一個頭節點 void BT_PreOrderNoRec3(BiTreePtr pNode) {while (!pNode)// 回溯到指向根節點的頭節點時退出{if( !pNode->bVisited )//判定是否已被訪問{ visit(pNode);pNode->isVisited = true;}if ( pNode->left && !pNode->left->isVisited )pNode = pNode->left;else if( pNode->right && !pNode->right->isVisited )pNode = pNode->right;else //回溯pNode = pNode->parent;} }
3. 中序遍歷(非遞歸實現)
// 用棧實現 void BT_InOrderNoRec1(BiTreePtr pNode) {stack<BiTreePtr> s;while (!pNode || !s.empty()){if (!pNode){s.push(pNode);pNode = pNode->left;}else{pNode = s.pop();visit(pNode);pNode = pNode->right;}} } // 不用棧實現 每個節點含父節點指針和isVisited【默認為false】的狀態變量 且該二叉樹含一個頭節點 void BT_InOrderNoRec2(BiTreePtr pNode) {while (!pNode) // 回溯到指向根節點的頭節點時退出{while (pNode->left && !pNode->left->isVisited)pNode = pNode->left;if (!pNode->isVisited){visit(pNode);pNode->isVisited=true;}if (pNode->right && !pNode->right->isVisited)pNode = pNode->right;elsepNode = pNode->parent;} }
4. 后序遍歷(非遞歸實現)
void BT_PostOrderNoRec(BiTreePtr pNode) {if(!pNode) return;stack<BiTreePtr> s;s.push(pNode);while (!s.empty()){BiTreePtr pvNode = s.pop();if (pvNode->isPushed)// 表示其左右子樹都已入棧,訪問該節點visit(pvNode);else{if (pvNode->right){pvNode->right->isPushed = false;S.push(pvNode->right);}if (pvNode->left){pvNode->left->isPushed = false;s.push(pvNode->left);}pvNode->isPushed = true;s.push(pvNode);}} }
5. 層序遍歷(使用隊列)
void BT_LevelOrder(BiTreePtr pNode) {if (!pNode) return;queue<BiTreePtr> q;q.push(pNode);BiTreePtr pvNode;while (!q.empty()){pvNode = q.pop();visit(pvNode);if (pvNode->left)q.push(pvNode->left); if (pvNode->right)q.push(pvNode->right); } }
..........
#include<bits/stdc++.h> using namespace std; char s[105]; typedef struct BiTNode {char data;struct BiTNode *lchild,*rchild; }BiTNode,*BiTree;int CreateBiTree(BiTree &T,int &index,int &n) {if(index==n)return 0;if(s[index]=='#'){T=NULL;index++;}else{T=(BiTree)malloc(sizeof(BiTNode));T->data=s[index];index++;CreateBiTree(T->lchild,index,n);CreateBiTree(T->rchild,index,n);}return 0; }void Visit(BiTree T) {if(T->data!='#')printf("%c",T->data); } void PostOrder(BiTree T) {if(T!=NULL){PostOrder(T->lchild);PostOrder(T->rchild);Visit(T);} } int main() {while(~scanf("%s",s)){BiTree T;int len=strlen(s);int index=0;CreateBiTree(T,index,len);PostOrder(T);printf("\n");}return 0; }總結
- 上一篇: mysql 执行计划_mysql执行计划
- 下一篇: 2017-9-17pat甲级 A