二叉樹作爲一種非常重要的數據結構,今天對其做簡單的回顧
1、二叉樹的定義
- typedef char ElementType;
- typedef struct BiTreeNode
- {
- ElementType data;
- struct BiTreeNode* lchild;
- struct BiTreeNode* rchild;
- }BiTreeNode, *BiTree;
(1)利用先序序列遞歸建立二叉樹
- //遞歸的建立一棵二叉樹
- //輸入爲二叉樹的先序序列
- void createBiTree(BiTree &T)
- {
- char data;
- data = getchar();
- if(data == '#')
- {
- T = NULL;
- }
- else
- {
- T = new BiTreeNode;
- T->data = data;
- createBiTree(T->lchild);
- createBiTree(T->rchild);
- }
- }
(2)利用廣義表建立二叉樹
- //通過廣義表建立二叉樹
- void createBiTreeWithGenList(BiTree &T)
- {
- stack<BiTree> s;//存放待輸入孩子的結點
- BiTree p = NULL;//用於生成新的結點
- int k = 0;//記錄期待的結點, k==1表示期待左孩子結點,k==2期待右孩子結點
- char ch = getchar();
- //處理根結點
- if(ch!='#')
- {
- p = new BiTreeNode;
- p->data = ch;
- p->lchild = NULL;
- p->rchild = NULL;
- T = p;//根結點
- }
- while((ch=getchar())!='#')
- {
- switch(ch)
- {
- case '(':
- s.push(p);//上一個生成的結點,即p入棧,p有孩子
- k = 1; //下一個插入的應爲左孩子結點
- break;
- case ',':
- k = 2; //下一個插入的應爲右孩子結點
- break;
- case ')':
- s.pop();//結點完成孩子的輸入,出棧
- break;
- default:
- p = new BiTreeNode;
- p->data = ch;
- p->lchild = NULL;
- p->rchild = NULL;
- if(k==1)
- s.top()->lchild = p;
- else
- s.top()->rchild = p;
- }
- }
- }
(3)輸出二叉樹的廣義表表示
- //以廣義表的方式輸出二叉樹
- void printBiTreeWithGenList(const BiTree&T)
- {
- if(T)
- {
- cout<<T->data;
- if(T->lchild ||T->rchild)//左右子樹不全空
- {
- cout<<"(";
- printBiTreeWithGenList(T->lchild);//遞歸輸出左子樹 ,可能爲空
- if(T->rchild)
- {
- cout<<",";
- printBiTreeWithGenList(T->rchild);
- }
- cout<<")";
- }
- }
- }
(4)二叉樹的銷燬
- //遞歸銷燬一棵二叉樹
- void destroyBiTree(BiTree &T)
- {
- if(T)
- {
- destroyBiTree(T->lchild);
- destroyBiTree(T->rchild);
- delete T;
- T = NULL;
- }
- }
(1)先序遞歸遍歷
- //遞歸先序遍歷二叉樹
- void preOrderTraverse(const BiTree &T)
- {
- if(T)
- {
- cout<<T->data<<" ";//輸出根節點值
- preOrderTraverse(T->lchild);//遍歷左子樹
- preOrderTraverse(T->rchild);//遍歷右子樹
- }
- }
(2)中序遞歸遍歷
- //遞歸中序遍歷二叉樹
- void inOrderTraverse(const BiTree &T)
- {
- if(T)
- {
- inOrderTraverse(T->lchild);//遍歷左子樹
- cout<<T->data<<" ";//輸出根節點值
- inOrderTraverse(T->rchild);//遍歷右子樹
- }
- }
(3)後序遞歸遍歷
- //遞歸後序遍歷二叉樹
- void postOrderTraverse(const BiTree &T)
- {
- if(T)
- {
- postOrderTraverse(T->lchild);//遍歷左子樹
- postOrderTraverse(T->rchild);//遍歷右子樹
- cout<<T->data<<" ";//輸出根節點值
- }
- }
4 、二叉樹的其他常見遞歸算法
(1)遞歸求樹的深度(高度)
- //遞歸求樹的深度
- int depthOfBiTree(const BiTree &T)
- {
- int ldepth;
- int rdepth;
- if(T==NULL)//空樹
- return 0;
- ldepth = depthOfBiTree(T->lchild);
- rdepth = depthOfBiTree(T->rchild);
- return (ldepth>rdepth)?(ldepth+1):(rdepth+1);
- }
(2)遞歸求樹的葉子結點個數
- //遞歸求二叉樹的葉子結點個數
- int leafCountOfBiTree(const BiTree &T)
- {
- if(T==NULL)
- return 0;
- if(T->lchild==NULL && T->rchild==NULL)
- return 1;
- return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);
- }
- //交換二叉樹的左右子女
- void exchangeChild(BiTree &T)
- {
- if(T)
- {
- BiTree temp = NULL;
- if(T->lchild ||T->rchild)
- {
- temp = T->lchild;
- T->lchild = T->rchild;
- T->rchild = temp;
- exchangeChild(T->lchild);
- exchangeChild(T->rchild);
- }
- }
- }
5、完整的測試代碼
- #include <cstdlib>
- #include <iostream>
- #include <stack>
- using namespace std;
- //二叉樹定義
- typedef char ElementType;
- typedef struct BiTreeNode
- {
- ElementType data;
- struct BiTreeNode* lchild;
- struct BiTreeNode* rchild;
- }BiTreeNode, *BiTree;
- //遞歸的建立一棵二叉樹
- //輸入爲二叉樹的先序序列
- void createBiTree(BiTree &T)
- {
- char data;
- data = getchar();
- if(data == '#')
- {
- T = NULL;
- }
- else
- {
- T = new BiTreeNode;
- T->data = data;
- createBiTree(T->lchild);
- createBiTree(T->rchild);
- }
- }
- //通過廣義表建立二叉樹
- void createBiTreeWithGenList(BiTree &T)
- {
- stack<BiTree> s;//存放待輸入孩子的結點
- BiTree p = NULL;//用於生成新的結點
- int k = 0;//記錄期待的結點, k==1表示期待左孩子結點,k==2期待右孩子結點
- char ch = getchar();
- //處理根結點
- if(ch!='#')
- {
- p = new BiTreeNode;
- p->data = ch;
- p->lchild = NULL;
- p->rchild = NULL;
- T = p;//根結點
- }
- while((ch=getchar())!='#')
- {
- switch(ch)
- {
- case '(':
- s.push(p);//上一個生成的結點,即p入棧,p有孩子
- k = 1; //下一個插入的應爲左孩子結點
- break;
- case ',':
- k = 2; //下一個插入的應爲右孩子結點
- break;
- case ')':
- s.pop();//結點完成孩子的輸入,出棧
- break;
- default:
- p = new BiTreeNode;
- p->data = ch;
- p->lchild = NULL;
- p->rchild = NULL;
- if(k==1)
- s.top()->lchild = p;
- else
- s.top()->rchild = p;
- }
- }
- }
- //以廣義表的方式輸出二叉樹
- void printBiTreeWithGenList(const BiTree&T)
- {
- if(T)
- {
- cout<<T->data;
- if(T->lchild ||T->rchild)//左右子樹不全空
- {
- cout<<"(";
- printBiTreeWithGenList(T->lchild);//遞歸輸出左子樹 ,可能爲空
- if(T->rchild)
- {
- cout<<",";
- printBiTreeWithGenList(T->rchild);
- }
- cout<<")";
- }
- }
- }
- //遞歸銷燬一棵二叉樹
- void destroyBiTree(BiTree &T)
- {
- if(T)
- {
- destroyBiTree(T->lchild);
- destroyBiTree(T->rchild);
- delete T;
- T = NULL;
- }
- }
- //遞歸先序遍歷二叉樹
- void preOrderTraverse(const BiTree &T)
- {
- if(T)
- {
- cout<<T->data<<" ";//輸出根節點值
- preOrderTraverse(T->lchild);//遍歷左子樹
- preOrderTraverse(T->rchild);//遍歷右子樹
- }
- }
- //遞歸中序遍歷二叉樹
- void inOrderTraverse(const BiTree &T)
- {
- if(T)
- {
- inOrderTraverse(T->lchild);//遍歷左子樹
- cout<<T->data<<" ";//輸出根節點值
- inOrderTraverse(T->rchild);//遍歷右子樹
- }
- }
- //遞歸後序遍歷二叉樹
- void postOrderTraverse(const BiTree &T)
- {
- if(T)
- {
- postOrderTraverse(T->lchild);//遍歷左子樹
- postOrderTraverse(T->rchild);//遍歷右子樹
- cout<<T->data<<" ";//輸出根節點值
- }
- }
- //遞歸求樹的深度
- int depthOfBiTree(const BiTree &T)
- {
- int ldepth;
- int rdepth;
- if(T==NULL)//空樹
- return 0;
- ldepth = depthOfBiTree(T->lchild);
- rdepth = depthOfBiTree(T->rchild);
- return (ldepth>rdepth)?(ldepth+1):(rdepth+1);
- }
- //遞歸求二叉樹的葉子結點個數
- int leafCountOfBiTree(const BiTree &T)
- {
- if(T==NULL)
- return 0;
- if(T->lchild==NULL && T->rchild==NULL)
- return 1;
- return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);
- }
- //遞歸交換二叉樹的左右子女
- void exchangeChild(BiTree &T)
- {
- if(T)
- {
- BiTree temp = NULL;
- if(T->lchild ||T->rchild)
- {
- temp = T->lchild;
- T->lchild = T->rchild;
- T->rchild = temp;
- exchangeChild(T->lchild);
- exchangeChild(T->rchild);
- }
- }
- }
- int main(int argc, char *argv[])
- {
- BiTree T = NULL;
- createBiTree(T);//建立二叉樹 如輸入AB#D##CE###
- // createBiTreeWithGenList(T);//如輸入A(B(,D),C(E))#
- cout<<"preOrder: "; //先序遍歷
- preOrderTraverse(T);
- cout<<endl;
- cout<<"inOrder: ";//中序遍歷
- inOrderTraverse(T);
- cout<<endl;
- cout<<"postOrder: ";//後序遍歷
- postOrderTraverse(T);
- cout<<endl;
- cout<<"depth: "<<depthOfBiTree(T)<<endl;//樹的高度
- cout<<"the count of leaf: "<<leafCountOfBiTree(T)<<endl;//葉子結點數
- cout<<"The tree after exchange: ";
- exchangeChild(T);
- printBiTreeWithGenList(T);
- destroyBiTree(T);//銷燬二叉樹,釋放空間
- system("PAUSE");
- return EXIT_SUCCESS;
- }
轉自:http://blog.csdn.net/sysu_arui/article/details/7865876