二叉樹的二叉鏈表存儲表示如下
//二叉樹的二叉鏈表存儲表示 typedef struct BiTNode { char data;//結點數據域 struct BiTNode* lchild, * rchild;//左右孩子指針 }*BiTree;
根據括號表示法的字符串創建樹(括號里的表示括號前結點的子結點,‘,’號左邊是左子結點,右邊是右子結點)
比如:a(b(d,e),c(f,g(h,i)))
表示的則是
//創建樹 void CreateBiTree(BiTree& T) { stack<BiTNode*> s;//用於確定需要操作的結點 BiTNode* p=NULL; int i = 0; bool child_Direct;//0表示左子結點,1表示右子結點 //按先序次序輸入二叉樹中結點的值(一個字符),創建二叉鏈表表示的二叉樹T string TreeStr; cin >> TreeStr; while (TreeStr[i] != '\0') { switch (TreeStr[i]) { case'('://左子結點 s.push(p); child_Direct = false; break; case')': s.pop(); case','://右子結點 child_Direct = true; break; default: p = new BiTNode; p->data = TreeStr[i]; p->lchild = p->rchild = NULL; if (T == NULL)//若根節點為空則p指向根節點 T = p; else { if (!child_Direct) s.top()->lchild = p; else s.top()->rchild = p; } break; } i++; } }
非遞歸先序、中序、后序遍歷
先序:
void PreOrderTraverse(BiTree T) { stack<BiTNode*> s; BiTNode* p = T, * q = new BiTNode(); while (p != NULL || !s.empty()) { if (p)//p非空 { cout << p->data; s.push(p);//根指針入棧 p = p->lchild;//遍歷左子樹 } else { p = s.top(); s.pop(); p = p->rchild;//遍歷右子樹 } } }
中序:
//中序遍歷 void InOrderTraverse(BiTree T) { stack<BiTNode*> s; BiTNode* p = T, * q = new BiTNode(); while (p != NULL || !s.empty()) { if (p)//p非空 { s.push(p);//根指針入棧 p = p->lchild;//遍歷左子樹 } else { p = s.top(); s.pop(); cout << p->data; p = p->rchild;//遍歷右子樹 } } }
后序:
//后序遍歷 void PostOrderTraverse(BiTree T) { BiTNode* p = T, * r = NULL; stack<BiTNode*> s; while (p != NULL || !s.empty()) { if (p != NULL) {//走到最左邊 s.push(p); p = p->lchild; } else { p = s.top(); if (p->rchild != NULL && p->rchild != r)//右子樹存在,未被訪問 p = p->rchild; else { s.pop(); cout << p->data; r = p;//記錄最近訪問過的節點 p = NULL;//節點訪問完后,重置p指針 } }//else }//while }
完整代碼
#include <iostream> #include <stack> #include <string> using namespace std; //二叉樹的二叉鏈表存儲表示 typedef struct BiTNode { char data;//結點數據域 struct BiTNode* lchild, * rchild;//左右孩子指針 }*BiTree; void Initial(BiTree& T) { T = new BiTNode; T = NULL; } //創建樹 void CreateBiTree(BiTree& T) { stack<BiTNode*> s;//用於確定需要操作的結點 BiTNode* p=NULL; int i = 0; bool child_Direct;//0表示左子結點,1表示右子結點 //按先序次序輸入二叉樹中結點的值(一個字符),創建二叉鏈表表示的二叉樹T string TreeStr; cin >> TreeStr; while (TreeStr[i] != '\0') { switch (TreeStr[i]) { case'('://左子結點 s.push(p); child_Direct = false; break; case')': s.pop(); case','://右子結點 child_Direct = true; break; default: p = new BiTNode; p->data = TreeStr[i]; p->lchild = p->rchild = NULL; if (T == NULL)//若根節點為空則p指向根節點 T = p; else { if (!child_Direct) s.top()->lchild = p; else s.top()->rchild = p; } break; } i++; } } //以括號表示法輸出二叉樹 void DispBTNode(BiTNode *&b) { if (b != NULL) { cout<<b->data; if (b->lchild != NULL || b->rchild != NULL) { cout<<"("; DispBTNode(b->lchild); if (b->rchild != NULL) cout<<(","); DispBTNode(b->rchild); cout<<")"; } } } #pragma region 遞歸遍歷 //先序 void PreOrderTraverseR(BiTree T) { if (T != NULL) { cout << T->data; PreOrderTraverseR(T->lchild); PreOrderTraverseR(T->rchild); } } //中序 void InOrderTraverseR(BiTree T) { if (T != NULL) { InOrderTraverseR(T->lchild); cout << T->data; InOrderTraverseR(T->rchild); } } //后序 void PostOrderTraverseR(BiTree T) { if (T != NULL) { PostOrderTraverseR(T->lchild); PostOrderTraverseR(T->rchild); cout << T->data; } } #pragma endregion #pragma region 非遞歸遍歷 //先序遍歷 void PreOrderTraverse(BiTree T) { stack<BiTNode*> s; BiTNode* p = T, * q = new BiTNode(); while (p != NULL || !s.empty()) { if (p)//p非空 { cout << p->data; s.push(p);//根指針入棧 p = p->lchild;//遍歷左子樹 } else { p = s.top(); s.pop(); p = p->rchild;//遍歷右子樹 } } } //中序遍歷 void InOrderTraverse(BiTree T) { stack<BiTNode*> s; BiTNode* p = T, * q = new BiTNode(); while (p != NULL || !s.empty()) { if (p)//p非空 { s.push(p);//根指針入棧 p = p->lchild;//遍歷左子樹 } else { p = s.top(); s.pop(); cout << p->data; p = p->rchild;//遍歷右子樹 } } } //后序遍歷 void PostOrderTraverse(BiTree T) { BiTNode* p = T, * r = NULL; stack<BiTNode*> s; while (p != NULL || !s.empty()) { if (p != NULL) {//走到最左邊 s.push(p); p = p->lchild; } else { p = s.top(); if (p->rchild != NULL && p->rchild != r)//右子樹存在,未被訪問 p = p->rchild; else { s.pop(); cout << p->data; r = p;//記錄最近訪問過的節點 p = NULL;//節點訪問完后,重置p指針 } }//else }//while } #pragma endregion int main() { BiTree b; Initial(b); //創建樹 CreateBiTree(b); //先序遍歷 cout << "先序遍歷:"; PreOrderTraverse(b); cout << endl; //中序遍歷 cout << "中序遍歷:"; InOrderTraverse(b); cout << endl; //后序遍歷 cout << "后序遍歷:"; PostOrderTraverse(b); }
程序示例: