關於二叉樹可以參考wiki:http://zh.wikipedia.org/zh-cn/%E4%BA%8C%E5%8F%89%E6%A0%91
/********************************************************** Description:參數傳遞:C++ 二叉樹的實現以及指標使用注意事項* Author:charley* DateTime:2010-12-8 11:00* Compile Environment:win7+vs2008***********************************************************/#include <iostream>using namespace std;//*************************************************************************************//二叉樹結點類的定義template<class T> //模版結構體struct TreeNode{ T data; //節點的內容 TreeNode <T> *Lchild,*Rchild; //節點的左子樹和右子樹//可選擇參數的預設建構函式 /*TreeNode(T nodeValue = T(),TreeNode<T> *leftNode = NULL,TreeNode<T> *rightNode = NULL ) :data(nodeValue),Lchild(leftNode),Rchild(rightNode){} */ };//**************************************************************************************//二叉樹的建立template <class T> //模版方法void createBinaryTree(TreeNode<T> *&root ) //傳遞指標的引用{ TreeNode<T>* p = root; T nodeValue ; cin>>nodeValue; if(nodeValue==-1) { root=NULL; } else { root=new TreeNode<T>(); //構造一個節點 root->data = nodeValue; createBinaryTree(root->Lchild); //遞迴構造左子樹 createBinaryTree(root->Rchild); //遞迴構造右子樹 }}//************************************************************************************//二叉樹的先序遍曆template <class T>void preOrder( TreeNode<T> * & p) //傳遞指標的引用{ if(p) { cout<<p->data<<" "; preOrder(p->Lchild); preOrder(p->Rchild); }}//**************************************************************************************//二叉樹的中序遍曆template <class T>void inOrder(TreeNode<T> * & p) //傳遞指標的引用{ if(p) { inOrder(p->Lchild); cout<<p->data<<" "; inOrder(p->Rchild); }}//**************************************************************************************//二叉樹的後序遍曆template <class T>void postOrder(TreeNode<T> *& p) //傳遞指標的引用{ if(p) { postOrder(p->Lchild); postOrder(p->Rchild); cout<<p->data<<" "; }}//*************************************************************************************//統計二叉樹中結點的個數template<class T>int countNode(TreeNode<T> * & p) //傳遞指標的引用{ if(p == NULL) return 0; return 1+countNode(p->Lchild)+countNode(p->Rchild);}//***********************************************************************************//求二叉樹的深度template<class T>int depth(TreeNode<T> *& p) //傳遞指標的引用{ if(p == NULL) return -1; int h1 = depth(p->Lchild); int h2 = depth(p->Rchild); if(h1>h2)return (h1+1); return h2+1;}//***********************************************************************************//二叉樹的消毀操作//容易混淆的錯誤聲明:void destroy(TreeNode<T>* p) 這種聲明會建立一個局部的臨時對象來儲存傳遞的指標//雖然2個指標都執行同一塊堆空間,delete局部指標 也會刪除二叉樹結構所佔用的堆記憶體//但是全域傳遞的那個指標將會是垃圾指標,會產生不可預料的錯誤//void destroy(TreeNode<T> *& p) 此函數的參數為全域指標的一個別名,代表全域指標rootNode本身//這樣p = NULL;能達到置null 指標的左右//可選的方案是在調用完destroy方法之後,在主函數中執行rootNode = NULL操作template<class T>void destroy(TreeNode<T> *& p) //傳遞指標的引用,消毀函數,用來消毀二叉樹中的各個結點{ if(p) {//錯誤 return之後 沒有執行delete p //return destroy(p->Lchild); //return destroy(p->Rchild);destroy(p->Lchild);destroy(p->Rchild);//delete只能釋放由使用者通過new方式在堆中申請的記憶體,//是通過變數聲明的方式由系統所聲明的棧記憶體不能使用delete刪除//delete和free函數一樣,不修改它參數對應指標指向的內容,也不修改指標本身,//只是在堆記憶體管理結構中將指標指向的內容標記為可被重新分配 delete p;//堆上記憶體釋放 棧上指標並不銷毀//此時p指向的地址未知,此時執行*p = ? 操作會導致不可預料的錯誤//但是可以重新賦值p = &x;//最好delete之後把P置空p = NULL; }}//********************************************************************************//主函數的設計 int main (){ TreeNode<int> * rootNode = NULL; int choiced = 0; while(true) { system("cls"); //清屏 cout<<"\n\n\n ---主介面---\n\n\n"; cout<<" 1、建立二叉樹 2、先序遍曆二叉樹\n"; cout<<" 3、中序遍曆二叉樹 4、後序遍曆二叉樹\n"; cout<<" 5、統計結點總數 6、查看樹深度 \n"; cout<<" 7、消毀二叉樹 0、退出\n\n"; cout<<" 請選擇操作:"; cin>>choiced; if(choiced == 0) return 0; else if(choiced == 1) { system("cls"); cout<<"請輸入每個結點,斷行符號確認,並以-1結束:\n"; createBinaryTree(rootNode ); } else if(choiced == 2) { system("cls"); cout<<"先序遍曆二叉樹結果:\n"; preOrder(rootNode); cout<<endl; system("pause"); //暫停螢幕 } else if(choiced == 3) { system("cls"); cout<<"中序遍曆二叉樹結果:\n"; inOrder(rootNode); cout<<endl; system("pause"); } else if(choiced == 4) { system("cls"); cout<<"後序遍曆二叉樹結果:\n"; postOrder(rootNode); cout<<endl; system("pause"); } else if(choiced == 5) { system("cls"); int count = countNode(rootNode); cout<<"二叉樹中結點總數為"<<count<<endl; system("pause"); } else if(choiced == 6) { system("cls"); int dep = depth(rootNode); cout<<"此二叉樹的深度為"<<dep<<endl; system("pause"); } else if(choiced == 7) { system("cls"); cout<<"二叉樹已被消毀!\n"; destroy(rootNode); cout<<endl; system("pause"); } else { system("cls"); cout<<"\n\n\n\n\n\t錯誤選擇!\n"; } }}假如本程式要產生的二叉樹如下:
則建立二叉樹輸入的順序為:8 7 5 1 –1 –1 –1 4 –1 –1 6 3 –1 –1 2 –1 -1
除了-1節點之外的就是實際建立的二叉樹
-1不是實際的節點、輸入-1僅表示子節點為空白返回繼續建立其他節點