二叉树常用操作

二叉树是比较重要的数据结构,它查询,删除,添加效率都很高,在很多算法比如回溯算法,递归算法,DFS都有利用到二叉树的模型,很多高级数据结构底层都是二叉树比如优先队列底层就是完全二叉树,并查集底层也是二叉树实现, 集合底层就是红黑数实现,后面的红黑树,ALV树,B+,B-,B树其实都是二叉树进化来其删除,推荐,查询更高。
这里首先给出二叉树基本操作包括增,删,查,4种遍历,以及一些操作后面陆续更新其他几种树
本代码都是c++实现
本人水平不是很高,望大家多多指点

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

struct BSTNode{     //声明二叉树 
	int data;
	BSTNode *left,*right;
};

/********************
@declde  	插入关键字   注意bt一定是指针的引用 
@param bt  当前节点的引用
@param key 关键字

********************/
bool insertValue(BSTNode*  &bt,int key){      
	if(bt==NULL){ 
		bt=new BSTNode;
		bt->data=key;
		bt->left=NULL;
		bt->right=NULL;
		return true;	
	}
	if(bt->data==key)
		return false;
	if(bt->data>key)
		return insertValue(bt->left,key);
	if(bt->data<key)
		return insertValue(bt->right,key);
	
} 


/********************
@declde 通过关键字去递归检索二叉树 查找成功返回其节点 否则返回NULL 
@param bt  当前节点的引用
@param key 关键字
@return    返回当前节点的指针 
********************/

BSTNode* SearchBST(BSTNode* &bt,int key){   //检索 
	if(bt==NULL||bt->data==key)
		return bt;
	return key<bt->data?SearchBST(bt->left,key):SearchBST(bt->right,key);	
}

/********************
@declde 通过关键字去递归检索二叉树 查找成功返回其节点 否则返回NULL 同时可以获取其父亲节点的指针 
@param bt  当前节点的引用
@param key 关键字
@param parent  父亲节点为一个指针的引用 
@param  temp  辅助指针 指向当前节点的父亲指针 初始默认值为空 
@return    返回当前节点的指针 
********************/

BSTNode* SearchBST(BSTNode* &bt,int key,BSTNode* &parent,BSTNode *temp=NULL){ 

	if(bt==NULL)
	{
		parent=NULL;
		return NULL;	
	}
	else if(bt->data==key){
	
		parent=temp;
		return bt;
	}
			
	return key<bt->data?SearchBST(bt->left,key,parent,bt):SearchBST(bt->right,key,parent,bt);	
}

BSTNode*  maxNode(BSTNode* bt,BSTNode* &parent,BSTNode *temp=NULL){
	if(bt==NULL){
		parent=NULL;
		return NULL;
	}
	
	if(bt->right==NULL){
		parent=temp;
		return bt;
	}
	
	return maxNode(bt->right,parent,bt);
}

BSTNode*  maxNode(BSTNode* bt){
	return bt->right!=NULL?maxNode(bt->right):bt;	
}




BSTNode* minNode(BSTNode* bt){   //获取树的最小值节点的指针 
	return bt->left?minNode(bt->left):bt;
}

BSTNode*  minNode(BSTNode* bt,BSTNode* &parent,BSTNode *temp=NULL){
	if(bt==NULL){
		parent=NULL;
		return NULL;
	}
	
	if(bt->left==NULL){
		parent=temp;
		return bt;
	}
	
	return minNode(bt->left,parent,bt);
}





/******************** 
3种基础遍历
递归方式太简单了没写
以下都是非递归利用到栈这种数据结构
其中后序遍历比较复杂 
**********************/ 



void  BSTPreLe(BSTNode*  &bt){			//非递归先序遍历
	stack<BSTNode*> s;
	BSTNode* p=bt;
	
	while(1){
		while(p){
			cout<<p->data;
			s.push(p);
			p=p->left;
		}
		
		if(s.empty())
			break;
		p=s.top()->right;
		s.pop();	
	}	
}


void  BSTIoTra(BSTNode*  &bt){			//非递归中序遍历
	stack<BSTNode*> s;
	BSTNode* p=bt;
	while(1){
		while(p){
			s.push(p);
			p=p->left;
		}
		
		if(s.empty())
			break;
		cout<<s.top()->data;
		p=s.top()->right;
		s.pop();	
	}	
}



void  BSTPoTra(BSTNode*  &bt){   //非递归后序遍历  重点难得理解   性质:搜索到当前节点 其栈里都为其祖先节点 
	stack<BSTNode*> s;
	BSTNode *last=NULL;  //标记指针 
	BSTNode* p=bt;
	while(1){
		while(p){
			s.push(p);
			p=p->left;
		}
		if(s.empty())
			break;
			
		if(last==s.top()->right){
			cout<<s.top()->data;
			last=s.top();
			s.pop();	
		}
		else{
			
			p=s.top()->right;
			last=NULL;
			
			
			
		}	
					
	}	
}

/*
层次遍历
利用队列实现 
*/ 


void  BSTLeTra(BSTNode*  &bt){  //层次遍历 
	
	queue<BSTNode*> q;
	q.push(bt);


	while(!q.empty()){
		cout<<q.front()->data;

		if(q.front()->left){
			q.push(q.front()->left);
		
		}
		
		if(q.front()->right){
			q.push(q.front()->right);
		
		}
		q.pop();	
	}
	
}


/*
重点在于什么时候换层操作 

*/ 


int   BSTMaxWidth(BSTNode*  &bt){  //h获取树的最大宽度(基于bfs搜索) 
	
	queue<BSTNode*> q;
	q.push(bt);
	BSTNode*  tail;      //辅助指针 
	BSTNode* last=bt;   //指向每一层最后一个节点 
	int max=0;         	 
	int count=0;       //记录每一层的节点数 
	while(!q.empty()){
		cout<<q.front()->data;
		count++;
		if(q.front()->left){
			q.push(q.front()->left);
		    tail=q.front()->left;
		}
		
		if(q.front()->right){
			q.push(q.front()->right);
		    tail=q.front()->right;
		}
		
		if(last==q.front()){   //进入下一层 
			max=max>count?max:count;
			count=0;
			cout<<endl;
			last=tail;
		}
		q.pop();	
	}
	
	return max;
	
}


/*****************************************************************
当前节点左右节点都存在 进行删除操作
找到左边子树的最大值节点或者找到右边子树的最小节点  替换掉将要删除的节点的值 然后去删除最大节点或最小节点  
注意最大节点左子树可能存在的情况或者最小节点可能存在的情况 不能直接进行删除 删除要传指针的引用 

******************************************************************/ 

void Delete1(BSTNode* p,BSTNode *  &r){   
	if(r->right==NULL){
		BSTNode *q;
		p->data=r->data;
		q=r;
		r=r->left;
		delete q;
	}
	else 
		Delete1(p,r->right);
}




void Delete(BSTNode* &p){
	BSTNode* q;
	if(p->left==NULL&&p->right==NULL)  
	{
		q=p;
		p=NULL;
		delete q;
	}
	else if(p->left==NULL){
		q=p;
		p=p->right;
		delete q;
	}
	else if(p->right==NULL){
		q=p;
		p=p->left;
		delete q;	    
	}
	//     5
	//   2  7
	// 1
	else{      //左右孩子都有 
		Delete1(p,p->left);
	}
	
}


bool BSTDelete(BSTNode* &bt,int key){  //删除操作接口 
	if(bt==NULL)
		return false;
	else if(bt->data==key){
		
		Delete(bt);
		return true;
	}
	
	return key<bt->data?BSTDelete(bt->left,key):BSTDelete(bt->right,key);
}



int BSTHeight(BSTNode* &bt){
	if(bt==NULL)
		return 0;
	else 
	{
		int left=BSTHeight(bt->left)+1;
		int right=BSTHeight(bt->right)+1;
		return left>right?left:right;
	}
	
	
}


int main(){
	BSTNode*  bt=NULL;
	insertValue(bt,5);
	insertValue(bt,2);
	insertValue(bt,1);
	insertValue(bt,7);
	
	BSTLeTra(bt);
	


	
	

		
	
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值