1. 程式人生 > >二叉排序樹的建立、插入、刪除、查詢、4種遍歷 C++完整實現

二叉排序樹的建立、插入、刪除、查詢、4種遍歷 C++完整實現

#include<iostream>
#include<string>
#include<queue>
using namespace std;

typedef int KeyType;
#define NUM 13
class BinSTree;
class BinStreeNode
{
public:
	KeyType key;
	BinStreeNode *lchild;
	BinStreeNode *rchild;
	BinStreeNode()
	{
		lchild=NULL;
		rchild=NULL;
	}
};

class BinSTree
{
public:
	BinStreeNode *root;
	BinSTree()
	{
		root=NULL;
	}
	~BinSTree()
	{
		//delete root;
	}
	BinStreeNode *BSTreeSearch(/*BinStreeNode *bt,*/KeyType k,BinStreeNode *&p);//查詢失敗返回NULL,p記錄待插入的父結點
	void BSTreeInsert(KeyType k);//bt用引用,插入結點為根結點,需要修改root
	int BSTreeDelete(KeyType k);
	void BSTreePreOrder(BinStreeNode *bt);
	void BSTreeInOrder(BinStreeNode *bt);
	void BSTreeAfOrder(BinStreeNode *bt);
	void BSTreeLevelTraverse(BinStreeNode *bt);//層次遍歷
	bool IsEmpty()
	{
		return root==NULL;
	}
};
/*
* 二叉排序樹查詢演算法
* 在根指標為bt的二叉排序樹中查詢元素k的節點,若查詢成功,則返回指向該節點的指標
* 查詢成功時,引數p指向查詢到的結點;查詢失敗時,引數p指向k應插入的父節點
*/
BinStreeNode *BinSTree::BSTreeSearch(/*BinStreeNode *bt,*/KeyType k,BinStreeNode *&p)
{
	BinStreeNode *q=NULL;
	q=root;
	while(q)
	{
		p=q;
		if(q->key==k)
			return p;
		else if(q->key>k)
			q=q->lchild;
		else
			q=q->rchild;
	}
	return NULL;
}
//插入操作
void BinSTree::BSTreeInsert(KeyType k)
{
	BinStreeNode *p=NULL,*q;
	q=root;
	if(BSTreeSearch(k,p)==NULL)//查詢失敗時才插入
	{
		BinStreeNode *r=new BinStreeNode;
		r->key=k;
		if(q==NULL)//根結點為空
		{
			root=r;
			return ;
		}
		if(p&&k<p->key)
			p->lchild=r;
		else if(p&&k>p->key)
			p->rchild=r;
	}
}
//先序遍歷
void BinSTree::BSTreePreOrder(BinStreeNode *bt)
{
	if(bt)
	{
		cout<<bt->key<<" ";
		BSTreePreOrder(bt->lchild);
		BSTreePreOrder(bt->rchild);
	}
}
//中序遍歷
void BinSTree::BSTreeInOrder(BinStreeNode *bt) //時間複雜度O(N);
{
	if(bt)
	{
		
		BSTreeInOrder(bt->lchild);
		cout<<bt->key<<" ";
		BSTreeInOrder(bt->rchild);
	}
}
//後序遍歷
void BinSTree::BSTreeAfOrder(BinStreeNode *bt)
{
	if(bt)
	{
		
		BSTreeAfOrder(bt->lchild);
		BSTreeAfOrder(bt->rchild);
		cout<<bt->key<<" ";
	}
}
//層次遍歷
void BinSTree::BSTreeLevelTraverse(BinStreeNode *bt)
{
	queue<BinStreeNode*> q;
	if(bt)
		q.push(bt);
	while(!q.empty())
	{
		cout<<q.front()->key<<" ";//訪問隊頭結點
		if(q.front()->lchild)
			q.push(q.front()->lchild);
		if(q.front()->rchild)
			q.push(q.front()->rchild);
		q.pop();
	}
	cout<<endl;
}
//二叉排序樹刪除操作,刪除成功返回1,失敗返回0.
int BinSTree::BSTreeDelete(KeyType k)
{
	BinStreeNode *f,*p,*q,*s;
	p=root;
	f=NULL;
	//查詢關鍵字為k的結點,同時將此結點的雙親找出來
	while(p&&p->key!=k)
	{
		f=p; //f記錄父結點
		if(p->key>k)
			p=p->lchild;
		else
			p=p->rchild;
	}
	if(!p)//找不到待刪除結點時返回
		return 0;
	if(p->lchild==NULL) //待刪除結點的左子樹為空
	{
		if(f==NULL)//待刪除結點為根結點
			root=p->rchild;
		else if(f->lchild==p)//待刪除結點是其雙親結點的左節點
			f->lchild=p->rchild;
		else                //待刪除結點是其雙親結點的右結點
			f->rchild=p->rchild;
		delete p;
	}
	else //待刪除結點有左子樹
	{
		q=p;
		s=p->lchild;
		while(s->rchild) //在待刪除結點的左子樹中查詢最右下結點,即查詢待刪除結點的中序前驅結點
		{
			q=s;
			s=s->rchild;
		}
		if( q == p )  
            q->lchild = s->lchild;  
        else  
            q->rchild = s->lchild;  
        p->key = s->key;  //值替代法刪除節點
        delete s; 
	}
	return 1;
}


int main()
{
	int a[NUM]={34, 18, 76, 13,12,11, 52, 82, 16, 67, 58, 73, 72 };
	BinSTree bst;
	BinStreeNode *pBt = NULL, *p = NULL, *pT = NULL;
	for(int i=0;i<NUM;i++)
	{
		bst.BSTreeInsert(a[i]);
	}
	pT = bst.BSTreeSearch(51, p ); //搜尋排序二叉樹 
	bst.BSTreeLevelTraverse(bst.root);
	if(pT)
	{
		cout<<pT->key<<endl;
	}
    bst.BSTreePreOrder(bst.root);  
    cout << endl;  
    bst.BSTreeDelete(13);   //刪除無左孩子的情況  
    bst.BSTreePreOrder(bst.root);  
    cout << endl;  
    bst.BSTreeDelete( 76 );   //刪除有左孩子的情況  
    bst.BSTreePreOrder(bst.root);  
    cout << endl;
	system("pause");
	return 0;
}

二叉排序樹的建立、插入、刪除、查詢、4種遍歷方式的C++完整實現版