c++樹及樹與二叉樹的轉換
此演算法中的樹結構為“左兒子有兄弟連結結構”
在這樣的一個二叉樹中,一個節點的左分支是他的大兒子節點,右分支為他的大兄弟節點。
這裡講的樹有遞迴前根,中根,後根遍歷,插入節點,插入兄弟節點,查詢結點,釋放記憶體這些功能。
重點說一下查詢節點這一演算法:
pSTreeNode CTree::Search( pSTreeNode pNode, TreeDataType Value )
{
if ( pNode == NULL )
return NULL;
if ( pNode->data == Value )
return pNode;
if ( pNode->pFirstChild == NULL && pNode->pNextBrother == NULL )
return NULL;
else
{
if ( pNode->pFirstChild != NULL ) //首先判斷根節點的左兒子節點是否為空,若不為空,通過引入指標來尋找節點
{
pSTreeNode pNodeTemp = Search( pNode->pFirstChild, Value );
if ( pNodeTemp != NULL )
return pNodeTemp;
else
{
return Search( pNode->pNextBrother, Value );
}
}
else //否則在根節點的右兄弟節點中尋找
return Search( pNode->pNextBrother, Value );
}
}
完整程式碼如下:
#include <iostream>
using namespace std;
typedef struct STreeNode* pSTreeNode;
typedef int TreeDataType;
//定義結構體
struct STreeNode
{
TreeDataType data;
pSTreeNode pFirstChild;
pSTreeNode pNextBrother;
//結構體建構函式
STreeNode( TreeDataType Value )
{
data = Value;
pFirstChild = NULL;
pNextBrother = NULL;
}
};
//定義類
class CTree
{
public:
CTree();
CTree( TreeDataType Value );
~CTree();
public:
void Insert( TreeDataType parentValue, TreeDataType Value ); // parentValue:該點的父親節點;Value:該點的值
void InsertBrother( pSTreeNode pParentNode, TreeDataType Value );
pSTreeNode Search( pSTreeNode pNode, TreeDataType Value );
void Preorder( pSTreeNode pNode ); // 前序遍歷
void Inorder( pSTreeNode pNode ); // 中序遍歷
void postorder( pSTreeNode pNode ); // 後序遍歷
void FreeMemory( pSTreeNode pNode ); // 釋放記憶體
public:
pSTreeNode pRoot;
};
//建構函式
CTree::CTree()
{
pRoot = NULL;
}
//建構函式
CTree::CTree( TreeDataType Value )
{
pRoot = new STreeNode( Value );
}
//解構函式
CTree::~CTree()
{
if (pRoot == NULL )
return;
FreeMemory( pRoot );
}
//釋放記憶體
void CTree::FreeMemory( pSTreeNode pNode )
{
if ( pNode == NULL )
return;
if ( pNode->pFirstChild != NULL )
FreeMemory( pNode->pFirstChild );
if ( pNode->pNextBrother != NULL )
FreeMemory( pNode->pNextBrother );
delete pNode;
pNode = NULL;
}
//插入節點
void CTree::Insert( TreeDataType parentValue, TreeDataType Value )
{
if ( pRoot == NULL )
return;
pSTreeNode pFindNode = Search( pRoot, parentValue );
if ( pFindNode == NULL )
return;
if ( pFindNode->pFirstChild == NULL )
{
pFindNode->pFirstChild = new STreeNode( Value );
return;
}
else
{
InsertBrother( pFindNode->pFirstChild, Value );
return;
}
}
//插入右兄弟節點
void CTree::InsertBrother( pSTreeNode pBrotherNode, TreeDataType Value )
{
if ( pBrotherNode->pNextBrother != NULL )
InsertBrother( pBrotherNode->pNextBrother, Value );
else
{
pBrotherNode->pNextBrother = new STreeNode( Value );
return;
}
}
//查詢函式
pSTreeNode CTree::Search( pSTreeNode pNode, TreeDataType Value )
{
if ( pNode == NULL )
return NULL;
if ( pNode->data == Value )
return pNode;
if ( pNode->pFirstChild == NULL && pNode->pNextBrother == NULL )
return NULL;
else
{
if ( pNode->pFirstChild != NULL )
{
pSTreeNode pNodeTemp = Search( pNode->pFirstChild, Value );
if ( pNodeTemp != NULL )
return pNodeTemp;
else
{
return Search( pNode->pNextBrother, Value );
}
}
else
return Search( pNode->pNextBrother, Value );
}
}
//前序遍歷
void CTree::Preorder( pSTreeNode pNode )
{
if (pNode == NULL)
return;
cout << " " << pNode->data << " ";
Preorder( pNode->pFirstChild );
Preorder( pNode->pNextBrother );
}
//中序遍歷
void CTree::Inorder( pSTreeNode pNode )
{
if ( pNode == NULL )
return;
Inorder( pNode->pFirstChild );
cout << " " << pNode->data << " ";
Inorder( pNode->pNextBrother );
}
//後序遍歷
void CTree::postorder( pSTreeNode pNode )
{
if ( pNode == NULL )
return;
postorder( pNode->pFirstChild );
postorder( pNode->pNextBrother );
cout << " " << pNode->data << " ";
}
//主函式
int main()
{
CTree* pTree = new CTree( 1 );
pTree->Insert( 1, 2 );
pTree->Insert( 1, 3 );
pTree->Insert( 1, 4 );
pTree->Insert( 1, 5 );
pTree->Insert( 1, 6 );
pTree->Insert( 1, 7 );
pTree->Insert( 4, 8 );
pTree->Insert( 5, 9 );
pTree->Insert( 5, 10 );
pTree->Insert( 6, 11 );
pTree->Insert( 6, 12 );
pTree->Insert( 6, 13 );
pTree->Insert( 10, 14 );
pTree->Insert( 10, 15 );
cout << "前序遍歷:" << endl;
pTree->Preorder( pTree->pRoot );
cout << endl;
cout << "中序遍歷:" << endl;
pTree->Inorder( pTree->pRoot );
cout << endl;
cout << "後序遍歷:" << endl;
pTree->postorder( pTree->pRoot );
cout << endl;
delete pTree;
pTree = NULL;
return 0;
}