一、二叉树

定义:每个节点都不能有多于两个的儿子的树。

二叉树节点声明:

 struct treeNode
{
elementType element;
treeNode * left;
treeNode * right;
}

应用:

中缀表达式——>后缀表达式(栈的应用)——>表达式树(栈的应用2)

栈的应用2:读取后缀表达式,操作数入栈,遇操作符后,指向栈里前两位元素t1和t2的指针出栈(t1先弹出,作为该操作符的右儿子),并将指向该操作符的指针入栈。

二、二叉查找树

定义:

结构性:二叉树;

排序性:右子树中最小值  >  X关键字  >  左子树中最大值(对任意节点关键字X均成立)

1、清空树(递归)makeEmpty

 searchTree * makeEmpty( searchTree * T)
{
if( T != NULL)
{
makeEmpty( T -> left);
makeEmpty( T -> right);
delete (T); // 基准情况
}
return T;
}

2、Find

searchTree * find( elementType X , searchTree * T)
{
if( T = NULL)
return NULL; //非空判断 if(X < T->element)
return find (X , T->left);
else
if(X > T->element)
return find(X , T->right);
else
return T; //找到元素X
}

3、findMin  &&  findMax(举一例,(非)递归法,利用其排序性找到相应节点)

递归法:

searchTree * findMax(  searchTree * T)
{
if( T = NULL)
return NULL; //非空判断
else
if(T->right == NULL)
return T; //基准情况
else
return findMax(T->right);
}

非递归法:

searchTree * findMax(  searchTree * T)
{
if( T = NULL)
return NULL; //非空判断
else
while(T->right != NULL)
T = T->right;

return T;
}

4、insert

searchTree * insert( elementType X , searchTree * T)
{
if( T == NULL)
{
T = searchTree New(searchTree);
if(T == NULL)
cout << "out of space." << endl;
else
{
T->element = X;
T->left = T->right = NULL;
}
}
else
if(X < T->element)
T->left = insert(X , T->left);
else
if(X > T->element)
T->right = insert(X , T->right); return T;
}

5、delete

searchTree * delete( elementType X , searchTree * T)
{
      searchTree * tem;
tem = (searchTree *) New searchTree;
if( T == NULL)
return NULL;
else
if(X < T->element)
T->left = delete(X , T->left);
else
if(X > T->element)
T->right = delete(X , T->right);
else
if(T->left && T->right)
{
tem = findMin(T->right);
T->element = tem->element;
// tem = delete(tem->element , tem);
T->right = delete(T->element , T->right);
}
else
{
tem = T;
if(T->left == NULL)
T = T->right;
if(T->right == NULL)
T = T->left;
delete(tem);
}
return T;
}

三、AVL树

定义:每个节点的左子树和右子树的高度最多差1的二叉查找树。(空树的高度定义为-1)

插入后,只有那些从 插入点根节点 的路径上的节点的平衡可能被改变,所以沿着  插入点   回溯到  根节点的这条路径并更新平衡信息,就可以找到破坏AVL平衡条件的节点。

(第一个这样的节点 即破坏性节点中最深的节点)。

破坏平衡性的节点设为a,则a的左右子树高度差为2,新节点插入点:

1、a的左儿子的左子树(单旋转)

2、a的左儿子的右子树(双旋转)

3、a的右儿子的左子树(单旋转)

4、a的右儿子的右子树(双旋转)

1、节点声明

struct avlNode
{
elementType element;
avlNode left;
avlNode right;
int height;
}

2、高度信息

static int height( avlNode *P)
{
if( P == NULL)
return -; //基准情况
else
return max( height(P->left) , height(P->right) ) + ;
}

3、节点插入

avlTree *insert(elementType X , avlTree *T)
{
if(T == NULL)
{
T = (avlTree*) New avlTree;
if(T == NULL)
cout << "out of space" << endl;
else
{
T->element = X;
T->left = T->right = NULL;
}
}
else
if(X < T->element)
{
T->left = insert (X , T->left);
if(height(T->left) - height(T->right) == )
{
if(X < T->left->element)
T = singleRotateWithLeft(T);
else
T = doubleRotateWithLeft(T);
}
}
else
if(X > T->element)
{
T->right = insert (X , T->right);
if(height(T->right) - height(T->left) == )
{
if(X > T->right->element)
T = singleRotateWithRight(T);
else
T = doubleRotateWithRight(T);
}
}
T->height = height(T); //更新高度信息
return T;
}

4、旋转(给出一组单双旋转)

static avlTree *singleRotateWithLeft(avlTree *T1)
{
avlTree *T2;
T2 = T1->left; T1->left = T2->right;
T2->right = T1;
T1->height = height(T1); //更新高度信息
T2->height = height(T2); return T2;
}
static avlTree *doubleRotateWithLeft(avlTree *T1)
{
T1->left = singleRotateWithRight(T1->left);
// 在旋转中已经有返回值,此时不写return亦可
rerurn singleRotateWithLeft(T1);
}

四、树的遍历(递归)

中序遍历:左-中-右

后序遍历:左-右-中(先遍历儿子)

前序遍历:中-左-右(先遍历祖先)

中序遍历:

void printTree(searchTree *T)
{
if(T != NULL)
{
printTree(T->left);
cout<< T->element << endl;
printTree(T->right);
}
}

二叉树-二叉查找树-AVL树-遍历的更多相关文章

  1. 二叉树与AVL树

    二叉树 什么是二叉树? 父节点至多只有两个子树的树形结构成为二叉树.如下图所示,图1不是二叉树,图2是一棵二叉树. 图1 普通的树                                    ...

  2. 二叉树,AVL树和红黑树

    为了接下来能更好的学习TreeMap和TreeSet,讲解一下二叉树,AVL树和红黑树. 1. 二叉查找树 2. AVL树 2.1. 树旋转 2.1.1. 左旋和右旋 2.1.2. 左左,右右,左右, ...

  3. 006-数据结构-树形结构-二叉树、二叉查找树、平衡二叉查找树-AVL树

    一.概述 树其实就是不包含回路的连通无向图.树其实是范畴更广的图的特例. 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合. 1.1.树的特性: 每个结点有零个或多个子 ...

  4. python常用算法(5)——树,二叉树与AVL树

    1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...

  5. 5分钟了解二叉树之AVL树

    转载请注明出处:https://www.cnblogs.com/morningli/p/16033733.html AVL树是带有平衡条件的二叉查找树,其每个节点的左子树和右子树的高度最多相差1.为了 ...

  6. 二叉树之AVL树

    高度为 h 的 AVL 树,节点数 N 最多2^h − 1: 最少N(h)=N(h− 1) +N(h− 2) + 1. 最少节点数n 如以斐波那契数列可以用数学归纳法证明: 即: N(0) = 0 ( ...

  7. 二叉树之AVL树的平衡实现(递归与非递归)

    这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...

  8. 面试题:什么叫平衡二叉查找树--AVL树

    查找.插入和删除在平均和最坏情况下都是O(log n) 增加和删除可能需要通过一次或多次树旋转来重新平衡这个树 节点的平衡因子是它的左子树的高度减去它的右子树的高度.带有平衡因子 1.0 或 -1 的 ...

  9. Avl树的基本操作(c语言实现)

    #include<stdio.h> #include<stdlib.h> typedef struct AvlNode *Position; typedef struct Av ...

随机推荐

  1. RobotFramework自动化测试之环境搭建安装教程(一)

    RobotFramework是基于Python语言的工具,所以装RF之前要先安装Python: Python现在有2.7跟3.5两个版本,如果是先装了3.5的话,是装不了2.7的.只有先装2.7的 才 ...

  2. JDK 伪异步编程(线程池)

    伪异步IO编程 BIO主要的问题在于每当有一个新的客户端请求接入时,服务端必须创建一个新的线程处理新接入的客户端链路,一个线程只能处理一个客户端连接.在高性能服务器应用领域,往往需要面向成千上万个客户 ...

  3. Hi,我还没死(屎)

    HDNOIP没考好,紧接着NOIP又到了,加紧练习:-)

  4. [转]使用 HTML5 IndexedDB API

    本地数据持久性提高了 Web 应用程序可访问性和移动应用程序响应能力 索引数据库 (IndexedDB) API(作为 HTML5 的一部分)对创建具有丰富本地存储数据的数据密集型的离线 HTML5 ...

  5. 每天一个linux命令--locate

    linux下,不知道自己安装的程序放在哪里了,可以使用locate命令进行查找. [hongye@dev107 ~]$ locate activemq.xml /home/hongye/hongyeC ...

  6. 在WPF下快速生成线的方法

    如果线较多时,在画布中用Path或Line生成时会比较慢.用DrawingVisual可以快速生成,这个在之前我的博客中已经提到.但在类库形式下生成的无法看到,保存成Image后再加入图层后成功显示. ...

  7. C#遍历enum类型

    对于enum类型: 使用foreach遍历enum类型的元素并填充combox foreach ( HatchStyle hs1 in Enum.GetValues(typeof(HatchStyle ...

  8. 数据结构:后缀自动机 WJMZBMR讲稿的整理和注释

    链接放在这里,有点难理解,至少我个人是的. 后缀自动机是一种有限状态自动机,其功能是识别字符串是否是母串的后缀.它能解决的问题当然不仅仅是判断是不是后缀这种事,跟字符串的连续子串有关的问题都可以往这个 ...

  9. HDU5331 : Simple Problem

    因为是二分图,所以最大独立集$=$总点数$-$最大匹配. 因为是树,所以具有贪心性质,设$f_i$表示$i$是否与其孩子匹配,$a_i$表示$i$的孩子里$f$为$0$的个数,则$f_i=[a_i&g ...

  10. BZOJ1795 : [Ioi2008]Pyramid Base 金字塔地基

    1.$B>0$ 二分答案,然后扫描线,线段树维护某个点作为左下角时的费用的最小值,支持区间加. 时间复杂度$O(n\log^2n)$. 2.$B=0$ 枚举左边界,则最优右边界可以通过双指针求出 ...