二叉树

二叉树:每个节点只有两个子树(左子树和右子树,子树可以为空)

如下图(百度百科中的)

二叉树中比较重要的就是遍历(先序,中序和后序)和搜索(BFS,DFS)了

从二叉树可以延伸出完全二叉树和满二叉树

完全二叉树为叶节点均在最后两层上,也是将节点从左至右依次插入(可以使用堆栈实现,先找到最左的节点,记录层数,然后依次回退,找到上一层最左的没有两个子节点的节点)

满二叉树:即每一层都装满了叶节点。

#include<stdio.h>
#include<queue>
#include<iostream>

using namespace std;
/*
二叉树 
插入、搜索、遍历,打印 
*/

struct Node{
	int value;
	Node* lchild;
	Node* rchild;
	
	Node(int v){
		value = v;
		lchild = NULL;
		rchild = NULL;
	}
}; 

//打印二叉树 
void printBinaryTree(Node *root){
	
} 

//此时是修改root本身的值,因此使用引用 
void insert(Node* &root, int val){
	//不存在根节点,即此时不存在二叉树 
	if(root == NULL){
		Node* node = new Node(val);
		root = node;
		return;
	}
	//优先将节点插入左子树 ,即只有在左子树非空,右子树为空时插入右子树 
	if(root->lchild != NULL && root->rchild == NULL){
		insert(root->rchild,val);
	} else{
		insert(root->lchild,val);
	}
	return;
} 

//利用已有的值创建一颗二叉树
Node* creatBinaryTree(int data[], int num){
	Node* root = NULL;
	for(int i=0;i<num;i++){
		insert(root,data[i]);
	}
	return root;
} 

//是否存在值为val的节点,深度优先遍历,递归搜索 
bool searchDFS(Node* root, int val){
	
	if(root == NULL){
		return false;
	} 
	if(root->value == val)
		return true;
	bool ans = false;
	ans |= searchDFS(root->lchild, val);
	ans |= searchDFS(root->rchild, val);
	return ans;
} 
//是否存在值为val的节点,广度优先遍历,递归搜索 
bool searchBFS(Node *root, int val){
	queue<Node*> q;
	if(root == NULL) return false;
	q.push(root);
	while(!q.empty()){
		Node*temp = q.front();
		q.pop();
		if(temp->value == val){
			return true;
		} 
		if(temp->lchild != NULL) q.push(temp->lchild);
		if(temp->rchild != NULL) q.push(temp->rchild);
	}
	return false;
}

//先序遍历 根,左子树,右子树 
void pre_order(Node*root){
	if(root == NULL) return;
	
	cout<<root->value<<" ";
	pre_order(root->lchild);
	pre_order(root->rchild);
	return;
} 
//中序遍历  左子树,根,右子树 
void in_order(Node*root){
	if(root == NULL) return;
	in_order(root->lchild);
	cout<<root->value<<" ";
	in_order(root->rchild);
	return;
} 
//后序遍历  左子树,右子树,根 
void post_order(Node*root){
	if(root == NULL) return;
	post_order(root->lchild);
	post_order(root->rchild);
	cout<<root->value<<" ";
	return;
} 

int main(){
	int data[10] = {0,1,2,3,4,5,6,7,8,9};
	Node* root = creatBinaryTree(data, 10);
	
	pre_order(root);
	cout<<endl;
	in_order(root);
	cout<<endl;
	post_order(root);
}

通过先序遍历和中序遍历构建二叉树

//通过先序遍历和中序遍历建立二叉树
Node* funC(int *predata, int *indata, int pnum, int inum){
	if(pnum==0) return NULL;
	if(inum==0) return NULL;
	
	Node* root = new Node(predata[0]);
	int i=0;
	for(; i<inum; i++){
		if(predata[0] == indata[i]) break;
	}
	root->lchild = funC(predata+1,indata,i,i);
	root->rchild = funC(predata+i+1,indata+i+1,pnum-i-1,inum-i-1);
	
	return root; 
}

类似的还可以通过后序遍历和中序遍历构建二叉树。

中序遍历是必要的,因为中序遍历区分了左子树和右子树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值