二叉排序树的创建删除中序输出&&平衡树
#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#
二叉排序树的创建删除中序输出&&平衡树的更多相关文章
- 二叉排序树(BST)创建,删除,查找操作
binary search tree,中文翻译为二叉搜索树.二叉查找树或者二叉排序树.简称为BST 一:二叉搜索树的定义 他的定义与树的定义是类似的,也是一个递归的定义: 1.要么是一棵空树 2.如果 ...
- PTA 中序输出叶子结点
6-8 中序输出叶子结点 (10 分) 本题要求实现一个函数,按照中序遍历的顺序输出给定二叉树的叶结点. 函数接口定义: void InorderPrintLeaves( BiTree T); T ...
- C++练习 | 创建并正序输出不带头结点的链表
#include <iostream> #include <cstdio> #include <stdlib.h> using namespace std; str ...
- 1064 Complete Binary Search Tree (30分)(已知中序输出层序遍历)
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...
- nyist 202 红黑树(二叉树中序遍历)
旋转对中序遍历没有影响,直接中序输出即可. #include <iostream> #include <cstdio> using namespace std; int n; ...
- PAT1020 (已知中序,后序遍历转前序遍历)
已知后序与中序输出前序(先序):后序:3, 4, 2, 6, 5, 1(左右根)中序:3, 2, 4, 1, 6, 5(左根右) 已知一棵二叉树,输出前,中,后时我们采用递归的方式.同样也应该利用递归 ...
- PAT甲级——1102 Invert a Binary Tree (层序遍历+中序遍历)
本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90577042 1102 Invert a Binary Tree ...
- PAT甲级|1151 LCA in a Binary Tree 先序中序遍历建树 lca
给定先序中序遍历的序列,可以确定一颗唯一的树 先序遍历第一个遍历到的是根,中序遍历确定左右子树 查结点a和结点b的最近公共祖先,简单lca思路: 1.如果a和b分别在当前根的左右子树,当前的根就是最近 ...
- 《剑指Offer》-004 -Java版二叉树先序和中序遍历返回原二叉树
如题 (总结要点) 注意空值 假定数据是没有问题的 前序(根左右) ,中序(左根右), 故每次的第一个节点就是根节点 没用数组的库函数,自己手写了两个方法 用Java代码写二叉树很舒服, 没有啥指针, ...
随机推荐
- jQuery插件开发 格式与解析
jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级 ...
- 线程、线程句柄、线程ID
什么是句柄:句柄是一种指向指针的指针.我们知道,所谓指针是一种内存地址.应用程序启动后,组成这个程序的各对象是住留在内存的.如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 ...
- 解决如何让AsyncTask终止操作
受到这个的启发终于结局了如何在AsyncTask运行中终止其操作. 单纯的onCancelled(true)是不行的 下面把代码贴出来~实现了登陆功能. AsyncTask简介,它使创建需要与用户界面 ...
- 查看哪些进程占用了SWAP分区?
在日常管理中,我们经常会遇到swap分区使用比较多,那么导致是那些进程使用的呢,其实我们可以通过/proc/pid/下的smaps来获得.使用下面的命令可以列出所有进程占用的swap分区的大小,分别我 ...
- JS高级程序设计学习笔记之基本包装类型
概述 基本类型:string.boolean.number 每当读取一个基本类型的值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据. 使用new操作符创建的 ...
- MySQL 一些小知识
1. 关于多表查询 我的理解:由于MySQL多表查询时表之间的连接是笛卡尔积的方式,所以尽量少使用多表查询,如果使用则使用嵌套语句 例:说明: `tb_notice_message` 表数量百万级别以 ...
- node-sqlite3-API-归纳总结
SQLITE3-API-LIST:API1. new sqlite3.Database(filename,[mode],[callback]) 返回数据库对象并且自动打开和连接数据库 它没有独立打开数 ...
- (一)CodeMirror - 基本应用
基本引用: <link rel="stylesheet" href="../lib/codemirror.css"> <script src= ...
- 洛谷 P3397 地毯
P3397 地毯 题目背景 此题约为NOIP提高组Day2T1难度. 题目描述 在n*n的格子上有m个地毯. 给出这些地毯的信息,问每个点被多少个地毯覆盖. 输入输出格式 输入格式: 第一行,两个正整 ...
- Ajax中send方法参数的使用
一般情况下,使用Ajax提交的参数多是些简单的字符串,可以直接使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null. 例如 : var url = " ...