树的建立 遍历
?
二叉樹是采用遞歸定義的,實(shí)現(xiàn)起來代碼簡潔(也許并不簡單)。并且它在具體的計(jì)算機(jī)科學(xué)中有很重要的運(yùn)用,是一種很重要的數(shù)據(jù)結(jié)構(gòu),二叉樹有三種遍歷和建立的方式。今天先學(xué)習(xí)一下它的建立和打印。
建立:
#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. 前序/中序/后序遍歷(遞歸實(shí)現(xiàn))
// 前序遍歷 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. 前序遍歷(非遞歸實(shí)現(xiàn))
// 用棧實(shí)現(xiàn) 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;}} }// 用棧實(shí)現(xiàn) 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);}} }// 不用棧實(shí)現(xiàn) 每個(gè)節(jié)點(diǎn)含父節(jié)點(diǎn)指針和isVisited【默認(rèn)為false】狀態(tài)變量 且該二叉樹含一個(gè)頭節(jié)點(diǎn) void BT_PreOrderNoRec3(BiTreePtr pNode) {while (!pNode)// 回溯到指向根節(jié)點(diǎn)的頭節(jié)點(diǎn)時(shí)退出{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. 中序遍歷(非遞歸實(shí)現(xiàn))
// 用棧實(shí)現(xiàn) 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;}} } // 不用棧實(shí)現(xiàn) 每個(gè)節(jié)點(diǎn)含父節(jié)點(diǎn)指針和isVisited【默認(rèn)為false】的狀態(tài)變量 且該二叉樹含一個(gè)頭節(jié)點(diǎn) void BT_InOrderNoRec2(BiTreePtr pNode) {while (!pNode) // 回溯到指向根節(jié)點(diǎn)的頭節(jié)點(diǎn)時(shí)退出{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. 后序遍歷(非遞歸實(shí)現(xiàn))
void BT_PostOrderNoRec(BiTreePtr pNode) {if(!pNode) return;stack<BiTreePtr> s;s.push(pNode);while (!s.empty()){BiTreePtr pvNode = s.pop();if (pvNode->isPushed)// 表示其左右子樹都已入棧,訪問該節(jié)點(diǎn)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. 層序遍歷(使用隊(duì)列)
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; }總結(jié)
- 上一篇: mysql 执行计划_mysql执行计划
- 下一篇: 2017-9-17pat甲级 A