#define max 10
using namespace std;
struct BinTreeNode //二叉查找樹的節點結構體
...{
int m_data;
struct BinTreeNode *lchild, *rchild;
BinTreeNode(int item, BinTreeNode *left = NULL, BinTreeNode *right = NULL)
: m_data(item), lchild(left), rchild(right)
//構造函數默認的lchild,rchild爲NULL
...{
}
};
struct MyQueue //用於層次遍歷的隊列
...{
BinTreeNode *array[max]; //定義一個指針數組作爲隊列用於保存指向節點的指針
int front, rear; //int型的隊首指針和隊尾指針
MyQueue()
...{
front = rear = 0;
}
};
class BinaryTree //二叉搜索樹類
...{
private:
BinTreeNode *root; //根節點指針
public:
BinaryTree()
...{
root = NULL;
}
void Insert(const int node) //迭帶插入的方法建二叉搜索樹
//ptr必須爲根節點指針的引用
...{
BinTreeNode *currentpointer; //當前節點指針
BinTreeNode *parentpointer; //父親節點指針
BinTreeNode *newpointer;
BinTreeNode *ptr = root;
newpointer = new BinTreeNode(node); //新動態分配一個節點
/**//*BinTreeNode *&ptr = root; //或者這樣寫也行但必須使用指針的引用
if(ptr == NULL)
{
ptr = newpointer;
}*/
if(root == NULL) //如果此時樹爲空,返回新開闢的節點
...{
root = newpointer;
}
else
...{
currentpointer = ptr; //保存root指針
while(currentpointer != NULL) //噹噹前節點不爲空的情況下
...{
parentpointer = currentpointer; //用指向父親節點的指針保存當前指針
if(currentpointer->m_data > node)
...{
currentpointer = currentpointer->lchild;
}
else
...{
currentpointer = currentpointer->rchild;
}
} //一直移動到是使parentpointer指向葉子節點而currentpointer爲NULL
//以下是將節點插入
if(parentpointer->m_data > node)
...{
parentpointer->lchild = newpointer;
}
else
...{
parentpointer->rchild = newpointer;
}
}
}
BinTreeNode *Creat(int data[],int len) //依次插入
...{
for(int i=0; i<len; i++)
...{
Insert(data[i]);
}
return root;
}
void PreOrder()
...{
cout<<"前序遍歷的結果爲:"<<endl;
PrePrint(root);
}
void preOrder() //前序非遞歸遍歷
...{
BinTreeNode *stack[50]; //定義一個指針數組作爲堆棧
BinTreeNode *p = root; //定義一個節點指針初始化指向頭節點
int top = 0;
cout<<endl<<"前序非遞歸遍歷:"<<endl;
while(p != NULL || top > 0)
...{
while(p != NULL)
...{
cout<<p->m_data<<" ";
stack[top++] = p; //p入棧
p = p->lchild;
}
p = stack[--top]; //p出棧
p = p->rchild;
}
}
void InOrder()
...{
cout<<endl;
cout<<"中序遍歷的結果爲:"<<endl;
InPrint(root);
}
void inOrder() //中序非遞歸遍歷
...{
BinTreeNode *stack[50]; //定義一個指針數組作爲堆棧
BinTreeNode *p = root; //定義一個節點指針初始化指向頭節點
int top = 0;
cout<<endl<<"中序非遞歸遍歷:"<<endl;
while(p != NULL || top > 0)
...{
while(p != NULL)
...{
stack[top++] = p; //p入棧
p = p->lchild;
}
p = stack[--top]; //p出棧
cout<<p->m_data<<" ";
p = p->rchild;
}
}
void PostOrder()
...{
cout<<endl;
cout<<"後序遍歷的結果爲:" <<endl;
PostPrint(root);
}
void Count()
...{
cout<<endl;
cout<<"葉子節點數爲:"<<CountLeafs(root)<<endl;
}
void PrePrint(BinTreeNode *p) //前序遍歷
...{
if(p != NULL)
...{
cout << p->m_data << ',';
PrePrint(p->lchild);
PrePrint(p->rchild);
}
}
void InPrint(BinTreeNode *p) //中序遍歷
...{
if(p != NULL)
...{
InPrint(p->lchild);
cout<< p->m_data<<',';
InPrint(p->rchild);
}
}
void PostPrint(BinTreeNode *p) //後序遍歷
...{
if(p != NULL)
...{
PostPrint(p->lchild);
PostPrint(p->rchild);
cout<< p->m_data<< ',';
}
}
void LevelOrder() //層次遍歷
...{
cout<<endl<<"層次遍歷:"<<endl;
MyQueue queue;
BinTreeNode *temp = root; //一個指向頭節點的指針temp
if(temp != NULL)
cout<<root->m_data<<" ";
queue.array[queue.rear] = temp; //頭節點指針入隊列
queue.rear = (queue.rear + 1) % max; //rear尾指針加一
while(queue.front <= queue.rear) //當隊列不空
...{
temp = queue.array[queue.front];
queue.front = (queue.front + 1) % max; //對首元素出隊列
if(temp->lchild != NULL) //如果有左孩子
...{
cout<<temp->lchild->m_data<<" "; //打印左孩子
queue.array[queue.rear] = temp->lchild; //左孩子入隊列
queue.rear = (queue.rear + 1) % max;
}
if(temp->rchild != NULL) //如果有右孩子
...{
cout<<temp->rchild->m_data<<" "; //打印右孩子
queue.array[queue.rear] = temp->rchild; //右孩子入隊列
queue.rear = (queue.rear + 1) % max;
}
}
}
BinTreeNode * Find(const int &c) //用迭帶的方法尋找特定的節點
...{
BinTreeNode *pCurrent = root;
if(pCurrent != NULL)
...{
while(pCurrent != NULL)
...{
if(pCurrent->m_data == c)
...{
return pCurrent;
}
else
...{
if(c > pCurrent->m_data)
pCurrent = pCurrent->rchild;
else
pCurrent = pCurrent ->lchild;
}
}
}
return NULL;
}
bool DeleteBT(const int &key) //刪除節點的函數定義
...{
BinTreeNode *q, *s;
BinTreeNode *current = root; //找到要刪除的節點
BinTreeNode *prt = NULL; //current的父親節點
while ((NULL != current) && (current->m_data != key))
//通過查找找到值爲key的節點和它的父親節點
...{
prt = current;
if (current->m_data > key)
current = current->lchild;
else
current = current->rchild;
}
if(current == NULL) //current爲NULL說明節點不存在
...{
cout<<"沒有此節點!"<<endl;
return false;
}
if(current->lchild == NULL && current->rchild == NULL)
//當找到的節點即沒有左孩子也沒有右孩子
...{
if(current == root)
...{
root = NULL;
}
else
...{
if(current == prt->lchild)
...{
prt->lchild = NULL;
}
else
...{
prt->rchild = NULL;
}
}
}
if(current->lchild == NULL && current->rchild != NULL)
//當找到的節點有右孩子而沒有左孩子
...{
if(current == root)
...{
current = current->rchild;
}
else
...{
if(current == prt->lchild) //如果當前節點是prt指向節點的左孩子
...{
prt->lchild = current->rchild;
}
else
...{
prt->rchild = current->rchild;
}
}
}
if(current->rchild == NULL && current->lchild != NULL)
//如果當前節點有左孩子而沒有右孩子
...{
if(current == root)
...{
current = current->lchild;
}
else
...{
if(current == prt->lchild)
...{
prt->lchild = current->lchild;
}
else
...{
prt->rchild = current->lchild;
}
}
}
if(current ->lchild != NULL && current->rchild != NULL)//當前節點左右孩子都有
...{
q = current; //用q保存current節點指針
s = current; //s是current的前驅指針
current = current->lchild;
//先向左走
while(current->rchild) //然後向右走到盡頭,其實就是尋找左子樹當中最大的節點
...{ //補充:尋找右子樹當中最小的節點也是可以的
s = current; //s指向current的前驅
current = current->rchild;
}
q->m_data = current->m_data; //用找到的節點替換當前節點
if(q != s) //將current節點從樹中拆下來
s->rchild = current->lchild;
else
q->lchild = current->lchild;
}
delete current; //釋放current指向的空間
current = NULL;
return true;
}
void destroy(BinTreeNode *current) //銷燬二叉樹
...{
if(current != NULL)
...{
destroy(current->lchild);
destroy(current->rchild);
delete current;
current = NULL;
}
}
int CountLeafs(BinTreeNode *current)
...{
if(current == NULL)
...{
return 0;
}
else
...{
if( current->lchild == NULL && current->rchild == NULL )
...{
return 1;
}
else
...{
int num1 = CountLeafs(current->lchild);
int num2 = CountLeafs(current->rchild);
return (num1+num2);
}
}
}
virtual ~BinaryTree()
...{
destroy(root);
}
};
main()
...{
BinaryTree myTree;
int a[]=...{6, 3, 4, 7, 8, 2, 6, 9, 0, 1};
myTree.Creat(a, max); //創建二叉搜索樹
myTree.PreOrder(); //先序遍歷
myTree.preOrder(); //前序非遞歸遍歷
myTree.InOrder(); //中序遍歷
myTree.inOrder(); //中序非遞歸遍歷
myTree.PostOrder(); //後序遍歷
myTree.LevelOrder(); //層次遍歷
myTree.Count(); //輸出葉子節點的數目
cout<<"輸入你想要找的節點"<<endl;
int x;
cin>>x;
if(myTree.Find(x)) //進行查找
cout<<"查找成功!"<<endl;
else
cout<<"查找失敗!"<<endl;
cout<<"輸入一個你想刪除的節點: "<<endl;
cin>>x;
if(myTree.DeleteBT(x)) //進行刪除
cout<<"刪除成功!"<<endl;
else
cout<<"刪除失敗!"<<endl;
myTree.PreOrder();
}