二叉搜索树 是满足下列条件的二叉树:
- 左子树上所有节点值均小于根节点值
- 右子树上所有节点值均不小于根节点值
- 左右子树也满足上述条件
二叉查找树的查找:
给定一棵二叉查找树,查找某节点p的过程就是递归的过程:
- 若当前节点cur值小于p的值,查找cur的左子树;
- 若当前节点cur值不小于p的值,查找cur的右子树;
- 递归上述过程,直到cur == p或者cur为空;
struct node{
int val;
pnode lchild;
pnode rchild;
}
pnode search_BST(pnode p,int x){
bool solve = false;
while(p && !solve){
if(x == p->val){
solve = true
}else if(x < p-> val1){
p = p->lchild;
}else{
p = p->rchild
}
}
if(p == nullptr){
cout<<"没有找到"<<x<<endl
}
return p;
}
二叉查找树的插入:
插入过程如下:
- 若当前的二叉查找树为空,则插入的元素为根节点,
- 过插入的元素值小于根节点,则将元素插入到左子树中,
- 若插入的元素值不小于根节点值,则将原宿插入到右子树中,
- 递归上述过程,直到找到插入点为叶子节点
pnode insert(pnode &root,int x){
if(root == nullptr){
pnode p = (pnode)new(len)
p->val = x;
p->lchild = nullptr;
p->rchild = nullptr;
root = p;
}else if(x < root->val){
root->lchild = insert(root->lchild,x)
}else{
root->rchild = insert(root->rchild,x)
}
return root;
}
二叉树的建立:
依次插入就完成了二叉树的建立。
二叉查找树的删除:
计待删除的节点为p,分三种情况进行处理:
- p为叶子节点(把该节点delete掉,将父节点的该子树释放了)
- p为单支节点(将p的子树与p的父亲节点相连,删除p即可)
- p的左子树和右子树均不为空(找到p的直接后继d,即p的右孩子的最左子孙,使用删除单支节点的方法,删除d,并让d的父亲节点dp成为d的右子树的父亲节点;同时,用d的值代替p的值)(对偶的,可以找到p的直接前去x,即p的左子树的最右子孙,删除x,并让x的父亲节点成为x的左子树的父亲节点)
struct node* deleteNode(struct node* t,int item)
{
if (t==nullptr)
return t;
if (item<t->key)
t->left=deleteNode(t->left,item);
else if (item>t->key)
t->right=deleteNode(t->right,item);
else
{
if (t->left==nullptr)
{
struct node *temp=t->right;
delete t;
return temp;
}
else if (t->right==nullptr)
{
struct node*temp=t->left;delete t;
return temp;
}
struct node* temp=findmin(t->right);
t->key=temp->key;
t->right=deleteNode(t->right,temp->key);
}
return t;
};
二叉树的遍历:
- 前序遍历(根->左->右)
- 中序遍历(左->根->右)
- 后序遍历(左->右->根)
- 深度遍历
- 广度遍历
void PreOrder(TreeNode *T)//非递归,前序遍历
{
if (T == NULL)
{
return;
}
stack<TreeNode*>s;
s.push(T);
TreeNode *temp;
while (!s.empty())
{
temp = s.top();
cout << temp->val;
s.pop();
if (temp->left)
{
s.push(temp->left);
}
if (temp->right)
{
s.push(temp->right);
}
}
}
void InOrder(TreeNode *T)//中序遍历
{
if (!T)
return;
InOrder(T->left);
cout << T->val;
InOrder(T->right);
}
void PostOrder(TreeNode *T)//后序遍历
{
if (!T)
return;
PostOrder(T->left);
PostOrder(T->right);
cout << T->val;
}
已知前序、中序遍历,求后序遍历:
void InPre2Post(char* inorder, char* preorder,int length){
TreeNode * node = new TreeNode;
node->elem, =*preorder;
int nRoot = 0;
for (;nRoot <length;nRoot++)
{
if(inorder[nRoot] == *preorder)
break;
}
InPre2Post(inorder,preorder+1,nRoot);
InPre2Post(inorder+nRoot+1,preorder+nRoot+1,length-(nRoot+1));
cout<<node->elem<<endl;
return;
}