二叉排序树的创建删除中序输出&&平衡树
#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代码写二叉树很舒服, 没有啥指针, ...
随机推荐
- Android自定义控件(一)——开关控件
Google 在 API 14 开始才新增了Switch 控件. 因此,我们可以选择自己封装一个Switch . 效果如图: View主要代码: public class SwitchView ext ...
- Cortex-A9 UART
一.Exynos4412 UART 的特性 Exynos4412 中UART,有4 个独立的通道,每个通道都可以工作于中断模式或DMA 模式,即 UART 可以发出中断或 DMA 请求以便在UART ...
- CentOS7--Xshell网络中断引起的vi编辑文件问题
在编写Python的程序时,由于不小心触碰网线使xshell出现网络中断问题,当再次以vi命令打开文件准备编辑时,发现爆出英文错误: 该错误的英文翻译大概是(1)另一个程序也在编译这个文件,如果是这样 ...
- 树状jquery导航条
$(function () { $(".leftsecoundtitle").css({ "display": "none" ...
- meta便签的用法
1.定义编码规则,<meta http-equiv="Content-Type" content="text/html; charset=utf-8" / ...
- phpwind 去除init.phpwind.net统计功能
修改的文件如下:global.phplib/staticpage.class.phprequire/template.phpsimple/index.php
- Java学习笔记--Swing2D图形
1.处理2D图形 要想使用java 2D库绘制图形,需要获得一个Graphics2D类对象.这个类是Graphics类的子类.paintComponent方法自动获得一个Graphics2D类对象,我 ...
- c# 菜单无限极分类-利用递归
表结构: 前台代码: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Web ...
- java生产者消费者并发协作
随着职务转变,代码荒废很久了,很多时间都是在沟通需求,作为一名技术员,不写代码就感觉是在自废武功,慢慢颓废了很多,今天重新回顾了下JAVA线程知识,基础知识就不梳理了,网上也很多,主要关键几个状态位( ...
- (转)C#在父窗口中调用子窗口的过程(无法访问已释放的对象)
C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象 笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中 ...