#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef struct Node{
Node *l, *r;
int v;
Node(){l = NULL; r = NULL;}
}*tree, Node;
tree build(tree p, int v){
if(p == NULL){
p = new Node();
p->v = v;
return p;
}
if(v < p->v)
p->l = build(p->l, v);
else if(v > p->v)
p->r = build(p->r, v);
else
return p;
return p;
}
void Delete(tree &T, int k){
Node *p = T;
Node *q, *s, *f;
f = NULL;
while(p){
if(p->v == k){
break;
}
f = p;
if(k < p->v){
p = p->l;
}
else{
p = p->r;
}
}
q = p;
if(!p)return;
if(p->l && p->r){
p = p->l;
while(p->r){
s = p;
p = p->r;
}
q->v = p->v;
s->r = p->l;
delete(p);
return;
}
else if(p->l){
q = p; p = p->l;
}
else{
q = p; p = p->r;
}
//cout << "*" << endl;
if(!f)T = p;
else if(q == f->l)f->l = p;
else f->r = p;
delete(q);
} void InOrder(tree p){
if(p == NULL)return;
InOrder(p->l);
printf("%d ", p->v);
InOrder(p->r);
} int main(){
int N;
while(~scanf("%d", &N)){
tree p;
p = NULL;
int v;
for(int i = ; i < N; i++){
scanf("%d", &v);
p = build(p, v);
}
InOrder(p); int m;
scanf("%d", &m);
for(int i = ; i < m; i++){
scanf("%d", &v);
Delete(p, v);
InOrder(p);
}
}
return ;
}

1)  对α的左儿子的左子树进行一次插入(左旋)

其中D是新插入的节点,红色节点K2是失去平衡的节点。需要对K1和K2进行左旋调整即将K1作为根,将K2作为K1的左子树,K1的右子树调整为K2的左子树。如下图所示

进行左旋变换   

2)对α的右儿子的右子树进行一次插入(右旋)

将K2的右子树更改为K1的左子树,K1的左子树更改为K2即完成的右旋,如下图所示

进行右旋

3)对α的左儿子的右子树进行一次插入(左右双旋)

左右双旋这里的左右指的是对α的左儿子的右子树进行插入时需要旋转。先对K1和K2进行右旋(跟第四种情况类似),然后再对K3和K2进行左旋,最终实现平衡。如下图所示

进行一次右旋进行一次左旋

4)对α的右儿子的左子树进行一次插入(右左双旋)

右左双旋:先对K1和K2进行左旋,然后在对K2和K3进行右旋,最终实现平衡。如下图所示

进行一次左旋进行一次右旋

平衡树:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std; struct TreeNode{
int v;
int H;
struct TreeNode *l;
struct TreeNode *r; }; typedef struct TreeNode *AvlTree, *Position; AvlTree FreeTree(AvlTree T){
if(T != NULL){
FreeTree(T->l);
FreeTree(T->r);
delete(T);
}
return NULL;
}
int Height(Position p){
if(p == NULL)
return -;
return p->H; }
void pushup(Position &K){
K->H = max(Height(K->l), Height(K->r)) + ;
} Position SingleRotateWithLeft(Position K2){
Position K1 = K2->l;
K2->l = K1->r;
K1->r = K2;
pushup(K1);
pushup(K2);
return K1;
}
Position SingleRotateWithRight(Position K2){
Position K1 = K2->r;
K2->r = K1->l;
K1->l = K2;
pushup(K1);
pushup(K2);
return K1;
} Position DoubleRotateWithLeft(Position K3){
K3->l = SingleRotateWithRight(K3->l);
K3 = SingleRotateWithLeft(K3);
}
Position DoubleRotateWithRight(Position K3){
K3->r = SingleRotateWithLeft(K3->r);
K3 = SingleRotateWithRight(K3);
} AvlTree insert(int x, AvlTree T){
if(T == NULL){
T = new TreeNode();
T->v = x;
T->H = ;
T->l = T->r = NULL;
}
else if(x < T->v){
T->l = insert(x, T->l);
if(Height(T->l) - Height(T->r) == ){
if(x < T->l->v)
T = SingleRotateWithLeft(T);
else
T = DoubleRotateWithLeft(T);
}
}
else if(x > T->v){
T->r = insert(x, T->r);
if(Height(T->r) - Height(T->l) == ){
if(x > T->r->v)
T = SingleRotateWithRight(T);
else
T = DoubleRotateWithRight(T);
}
}
pushup(T);
return T;
}
AvlTree Visit(int X, AvlTree T){
if(T == NULL)
return NULL;
if(X < T->v)
return Visit(X, T->l);
if(X > T->v)
return Visit(X, T->r);
return T;
}
void PreVisit(AvlTree T){
if(T == NULL)
return;
printf("%d ", T->v);
PreVisit(T->l);
PreVisit(T->r);
}
void InVisit(AvlTree T){
if(T == NULL)
return;
InVisit(T->l);
printf("%d ", T->v);
InVisit(T->r);
}
int main(){
AvlTree T = FreeTree(NULL);
// puts("**");
int i;
for(i = ; i <= ; i++)
T = insert(i, T);
for(i = ; i >= ; i--)
T = insert(i, T);
T = insert(, T);
T = insert(, T); printf("InOrder: ");
InVisit(T);
printf("\nPreOrder: ");
PreVisit(T);
putchar('\n');
return ;
}

参考博客:http://blog.csdn.net/zitong_ccnu/article/details/11097663#

二叉排序树的创建删除中序输出&&平衡树的更多相关文章

  1. 二叉排序树(BST)创建,删除,查找操作

    binary search tree,中文翻译为二叉搜索树.二叉查找树或者二叉排序树.简称为BST 一:二叉搜索树的定义 他的定义与树的定义是类似的,也是一个递归的定义: 1.要么是一棵空树 2.如果 ...

  2. PTA 中序输出叶子结点

    6-8 中序输出叶子结点 (10 分)   本题要求实现一个函数,按照中序遍历的顺序输出给定二叉树的叶结点. 函数接口定义: void InorderPrintLeaves( BiTree T); T ...

  3. C++练习 | 创建并正序输出不带头结点的链表

    #include <iostream> #include <cstdio> #include <stdlib.h> using namespace std; str ...

  4. 1064 Complete Binary Search Tree (30分)(已知中序输出层序遍历)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  5. nyist 202 红黑树(二叉树中序遍历)

    旋转对中序遍历没有影响,直接中序输出即可. #include <iostream> #include <cstdio> using namespace std; int n; ...

  6. PAT1020 (已知中序,后序遍历转前序遍历)

    已知后序与中序输出前序(先序):后序:3, 4, 2, 6, 5, 1(左右根)中序:3, 2, 4, 1, 6, 5(左根右) 已知一棵二叉树,输出前,中,后时我们采用递归的方式.同样也应该利用递归 ...

  7. PAT甲级——1102 Invert a Binary Tree (层序遍历+中序遍历)

    本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90577042 1102 Invert a Binary Tree ...

  8. PAT甲级|1151 LCA in a Binary Tree 先序中序遍历建树 lca

    给定先序中序遍历的序列,可以确定一颗唯一的树 先序遍历第一个遍历到的是根,中序遍历确定左右子树 查结点a和结点b的最近公共祖先,简单lca思路: 1.如果a和b分别在当前根的左右子树,当前的根就是最近 ...

  9. 《剑指Offer》-004 -Java版二叉树先序和中序遍历返回原二叉树

    如题 (总结要点) 注意空值 假定数据是没有问题的 前序(根左右) ,中序(左根右), 故每次的第一个节点就是根节点 没用数组的库函数,自己手写了两个方法 用Java代码写二叉树很舒服, 没有啥指针, ...

随机推荐

  1. 利用扩展双屏技术及Chrome浏览器,高速剖析优秀网页Div及CSS构成,并高效实现原型创作

    作为一个Web前台设计人员,应该充分利用可利用的硬件条件及专业的软件工具,迅速进入到高效氛围其中.实践中,我们能够利用扩展桌面双屏技术及Chrome浏览器高速剖析优秀网页Div及CSS构成,并高速实现 ...

  2. LoadRunner测试下载功能点脚本(方法二)

    在上一篇<LoadRunner下载功能点脚本(方法一)>中,实现的脚本仅是录制下载功能点的脚本,现在性能需求的场景更改如下: 性能需求:对系统某页面中,点击下载并将下载文件保存到本地电脑的 ...

  3. C/C++笔试准备(2)

    问题:编辑距离,是指将一个字符串变为另一个字符串,仅可以3种操作:修改一个字符,删除一个字符,插入一个字符.the变成that:删除e,插入a,插入t.20’ 实现编辑距离算法. 解算:利用动态规划的 ...

  4. 多路复用I/O poll()

    1.基本知识 poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制.poll和selec ...

  5. css_day7

  6. compass模块----Utilities

    引入Utilities: @import "compass/utilities"; 分别引入: @import "compass/utilities/color" ...

  7. 学习okhttp wiki--Connections.

    Connections 尽管你只提供了URL,OkHttp使用三种类型来创建它和你的web服务器的连接:URL,地址(Address)和路由(Route). URLs URLs (例如 https:/ ...

  8. java equals 心得体会

    要记住最有用的一点: equals 在已经被系统定义好的类中 是已经被重写好了的 父类中的 equals方法是比较的两个对象是否指向同一引用 在被定义除了父类以外比较的是两个对象的内容 因此 人为定义 ...

  9. OpenGL ES 2.0 符点精度

    片元着色器中使用符点相关类型的变量时与顶点着色器中有所不同,在顶点着色器中直接声明使用即可,而在片元着色器中必须指定精度. lowp 低 mediump 中 highp 高 指定整个着色器中符点相关类 ...

  10. GDB调试一

    http://blog.csdn.net/haoel/article/details/2881 GDB主要调试的是C/C++的程序.要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行 ...