二叉树:每个节点只有两个子树(左子树和右子树,子树可以为空)
如下图(百度百科中的)
二叉树中比较重要的就是遍历(先序,中序和后序)和搜索(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;
}
类似的还可以通过后序遍历和中序遍历构建二叉树。
中序遍历是必要的,因为中序遍历区分了左子树和右子树。