AVL树的实现

合集下载

AVL树研究与实现

AVL树研究与实现

AVL树研究与实现作者:解晨来源:《电脑知识与技术》2013年第07期摘要:计算机最广为人知的优点之一是其能储存大量的数据,如今随着时代的发展,储存容量更是犹如日进千里一般极速扩展,大容量的硬盘、U盘早已随处可见。

然而,要在巨大的数据中搜索出需要的内容却不是一件容易的事,由此,为了能减少在搜索储存数据上的开销,各种适应于不同访问搜索背景的数据结构应运而生。

树,便是计算机学科中最基本的数据结构之一,提供了快速的储存和访问性能。

该文探究了带有平衡条件的二叉查找树——AVL树的原理,并对其使用C语言进行了实现。

关键词:数据结构;平衡二叉查找树;AVL树中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2013)07-1532-04对于大量的输入数据,普通的线性数据结构访问时间太慢,例如,对于一个有N个数据的线性数据结构,假设对每个数据的访问几率大致相同,每个数据每次访问有1/N的机会被访问,由于是线性数据,因此每个数据的访问花销可以经过一定的排列,最通常的是访问第一个数据花销1个单位时间,第二个2个单位时间,第三个3各单位时间……第N个N各单位时间,于是访问一次的平均花销为(N+[N2])/2N = (1+N)/ 2,用计算机专业的符号来说,其访问运行时间可以用O(N)来表示,即访问一次线性数据结构的花销在N这个数量级上。

使用树这一数据结构可将访问花销将至logN这个数量级上,也即O(logN),这里logN是以二为底的N的对数。

可以对比一下,若N=1267650600228229401496703205376,则logN=100。

数字越大,则O(N)与O(logN)相差越大。

一般来说,计算机学科中使用的最基本的树为二叉查找树,下图是一颗二叉树的简单示意图:图1 二叉树示意图二叉查找树则是在二叉树的基础上得来。

假设在一颗二叉树中,每个节点都有一个关键词值,并且关键词值都是互异且可以比较,若对于此二叉树中的每个节点,其左子树中所有节点的关键词值小于其本身关键词值,其右子树中所有关键词值大于其本身关键词值,则此二叉树为二叉查找树。

C++实现AVL树的完整代码

C++实现AVL树的完整代码

C++实现AVL树的完整代码AVL树的介绍AVL树是⼀种⾃平衡的⼆叉搜索树,它通过单旋转(single rotate)和双旋转(double rotate)的⽅式实现了根节点的左⼦树与右⼦树的⾼度差不超过1,。

这有效的降低了⼆叉搜索树的时间复杂度,为O(log n)。

那么,下⾯⼩编将详细介绍C++实现AVL 树的代码。

最后⼀步提供可靠的代码实现这⾥先粘贴代码给⼤家的忠告,⼀定要及时去实现,不然之后再实现要花更多的时间/**平衡⼆叉树应该有些功能*插⼊删除查找*前序遍历中序遍历后序遍历层次遍历*统计结点数⽬*///代码已经调好,写了很久才写出来#ifndef _AVLTREE_#define _AVLTREE_#include<iostream>#include<vector>#include<queue>#include<map>using namespace std;#define MAXFACTOR = 2;template<class Key , class E>class AVLNode{private:Key key;E value;AVLNode<Key,E>* left;AVLNode<Key,E>* right;AVLNode<Key,E>* parent;public:AVLNode():left(nullptr),right(nullptr),parent(nullptr){}AVLNode(Key _key,E _value , AVLNode<Key,E>* _parent = nullptr,AVLNode<Key,E>*_left = nullptr, AVLNode<Key,E>*_right = nullptr):key(_key),value(_value),left(_left),right(_right),parent(_parent){}bool isLeaf(){return left==nullptr && right == nullptr ;}//元素设置Key getKey() const { return key;}void setKey(Key set) {key = set;}E getValue() const { return value;}void setValue(E set) {value = set;}AVLNode<Key,E>* getLeft() { return left; }void setLeft (AVLNode< Key,E >* set){ left = set;}AVLNode<Key,E>* getRight() { return right;}void setRight (AVLNode<Key,E>* set) {right = set ;}AVLNode<Key,E>* getParent() {return parent;}void setParent(AVLNode<Key,E>* set) { parent = set;}};template<class Key , class E>class AVLTree{private:AVLNode<Key,E>* root;void clear(AVLNode<Key,E>* &r){if(r==nullptr)return;delete r;}void Init(){root = new AVLNode<Key,E>();root=nullptr;}void preOrder(AVLNode<Key,E>* r,void(*visit) (AVLNode<Key,E> * node)) {if(r==nullptr)return;(*visit) (r);preOrder(r->getLeft() , visit);preOrder(r->getRight(), visit);}void inOrder(AVLNode<Key,E>* r , void(*visit)(AVLNode<Key,E>* node) ) {if(r==nullptr)return;inOrder(r->getLeft() , visit);(*visit)(r);inOrder(r->getRight(),visit);}void postOrder(AVLNode<Key,E>*r , void (*visit) (AVLNode<Key,E>* node)) {if(r==nullptr)return;postOrder(r->getLeft(),visit);postOrder(r->getRight(),visit);(*visit)(r);}void levelOrder(AVLNode<Key,E>*r , void (*visit) (AVLNode<Key,E>* node)) {queue< AVLNode<Key,E>* > q;if(r==nullptr)return;q.push(r);while( ! q.empty() ){AVLNode<Key,E>* tmp = q.front();q.pop();(*visit)(tmp);if(tmp->getLeft() ) q.push(tmp->getLeft() );if(tmp->getRight()) q.push(tmp->getRight());}}AVLNode<Key,E>* find(AVLNode<Key,E>* r,Key k){if(r==nullptr)return nullptr;if(k == r->getKey() ) return r;else if( k < r->getKey()){find(r->getLeft(),k);}else {find(r->getRight(),k);}}//Find the smallest element in the avl treeAVLNode<Key,E>* getMin(AVLNode<Key,E>* r){if(r->getLeft() == nullptr) return r;else{getMin(r->getLeft());}}//Remove the smallest elementAVLNode<Key,E>* deleteMin(AVLNode<Key,E>* rt){if(rt->getLeft() == nullptr) return rt->getRight();else{rt->setLeft(deleteMin(rt->getLeft()));}AVLNode<Key,E>* leftRotate(AVLNode<Key,E>* node){if( node == nullptr) return nullptr;AVLNode<Key,E>* newHead = node->getRight();node->setRight( newHead -> getLeft() );newHead -> setLeft( node );return newHead;}AVLNode<Key,E>* rightRotate(AVLNode<Key,E>* node){if(node == nullptr)return nullptr;AVLNode<Key,E>* newHead = node->getLeft();node->setLeft( newHead->getRight() );newHead ->setRight(node);return newHead;}int getHeight(AVLNode<Key,E>*node){if(node == nullptr)return 0;if(node->isLeaf())return 1;else return ( getHeight( node->getLeft() ) > getHeight( node->getRight() ) ? getHeight( node->getLeft() ) : getHeight( node->getRight() ) ) + 1; }int getBalanceFactor(AVLNode<Key,E>* node){return getHeight(node->getLeft()) - getHeight(node->getRight() );}AVLNode<Key,E>* balance(AVLNode<Key,E>* node){if(!node) return nullptr;else if ( getBalanceFactor( node ) == 2){if(getBalanceFactor( node ->getLeft() ) == 1){node = rightRotate(node);}else{node->setLeft(leftRotate( node->getLeft() ) );node = rightRotate(node);}}else if(getBalanceFactor( node ) == -2){if(getBalanceFactor( node->getRight()) == -1){node = leftRotate(node);}else{node->setRight( rightRotate( node->getRight() ) );node = leftRotate(node);}}return node;}AVLNode<Key,E>* insert( AVLNode<Key,E>* root ,const pair<Key,E>& it) {if(root == nullptr){return new AVLNode<Key,E>(it.first , it.second,NULL,NULL,NULL);}else if (it.first < root->getKey() ){root ->setLeft( insert(root->getLeft() , it) ) ;}else{root ->setRight( insert(root->getRight() , it) );root = balance(root);return root;}AVLNode<Key,E>* remove(AVLNode<Key,E>* node , const Key k){if(node == nullptr) return nullptr;if(node->getKey() > k){node->setLeft( remove(node->getLeft() , k) );node = balance(node);}else if(node->getKey() < k){node->setRight( remove(node->getRight(), k) );node = balance(node);}else if(node->getKey() == k){if(! node->isLeaf() ){AVLNode<Key,E>* tmp = getMin(node->getRight() );node->setKey( tmp->getKey() );node->setValue( tmp->getValue() );node->setRight( deleteMin(node->getRight() ) );delete tmp;}else {AVLNode<Key,E>* tmp = node;node = (node->getLeft() != nullptr) ? node->getLeft() : node->getRight() ; delete tmp;}}return node;}public:~AVLTree(){clear(root);}AVLTree(){/*Init();*/ root = nullptr; }//四种遍历⽅式void preOrder( void (*visit)(AVLNode<Key,E>* r)){preOrder(root,visit);}void inOrder(void (*visit)(AVLNode<Key,E>* r)){inOrder(root,visit);}void postOrder(void (*visit)(AVLNode<Key,E>* r)){postOrder(root,visit);}void levelOrder( void(*visit)(AVLNode<Key,E>*r) ){levelOrder(root,visit);}//插⼊void insert(const pair<Key,E> &it){root = insert(root,it);}//删除void remove(const Key& k){remove(root,k);}bool find(const Key&k){return find(root,k);}};#endif//AVLtest.cpp#include"NewAvl.h"#include<iostream>using namespace std;template<typename Key,typename E>void traverse(AVLNode<Key,E>* root){cout<<root->getKey()<<" "<<root->getValue()<<" "; cout<<endl;}int main(){AVLTree<int,int>* tree = new AVLTree<int ,int>; for(int i = 0 ; i < 5 ; i ++){tree->insert(make_pair(i,i));}tree->remove(1);cout<<"PreOrder: "<<endl;tree->preOrder(traverse);cout<<endl;cout<<"LevelOrder: "<<endl;tree->levelOrder(traverse);cout<<endl;cout<<"InOrder: "<<endl;tree->inOrder(traverse);cout<<endl;cout<<"PostOrder: "<<endl;tree->postOrder(traverse);cout<<endl;cout<<tree->find(2)<<endl;tree->insert(make_pair(9,9));tree->levelOrder(traverse);}运⾏结果以上就是C++实现AVL树的完整代码的详细内容,更多关于C++ AVL树的资料请关注其它相关⽂章!。

AVL树的c语言实现

AVL树的c语言实现

AVL树的c语言实现AVL树的c语言实现导语:C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的'机器码以及不需要任何运行环境支持便能运行的编程语言。

下面我们来看看AVL树的c语言实现,希望对大家有所帮助。

AVL树的c语言实现:在计算机科学中,AVL树是最先发明的自平衡二叉查找树。

在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。

查找、插入和删除在平均和最坏情况下都是O(log n)。

增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

1.节点(1)节点的定义1 2 3 4 5 6 7 8 9 typedef int KeyType;typedef struct AvlNode{KeyType key; //数据AvlNode *leftchild; //左孩子AvlNode *rightchild; //右孩子AvlNode *parent; //双亲结点int balance; //平衡因子}AvlNode,*AvlTree;(2)结点的创建1 2 3 4 5 6 7 8 9101112 AvlNode *BuyNode(){AvlNode *p =(AvlNode *)malloc(sizeof(AvlNode));if( p != NULL){p->leftchild = NULL;p->rightchild = NULL;p->parent = NULL;p->balance = 0;}return p;}2.旋转如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。

这种失去平衡的可以概括为4种姿态:左单旋转,右单旋转,左平衡,右平衡。

(1)左单旋转:也叫左左旋转。

【AVL树的c语言实现】。

平衡二叉树提高搜索和插入的效率

平衡二叉树提高搜索和插入的效率

平衡二叉树提高搜索和插入的效率平衡二叉树(Balanced Binary Tree),又称为AVL树,是一种具有平衡性质的二叉搜索树。

它通过在构建和插入节点时,保持树的平衡,从而提高搜索和插入操作的效率。

本文将介绍平衡二叉树的概念、性质以及如何实现和使用。

一、平衡二叉树的概念平衡二叉树是指在二叉搜索树的基础上,要求其任意节点的左子树和右子树的高度差不超过1。

这样的要求使得平衡二叉树的搜索和插入操作时间复杂度都能保持在O(logn)级别,相比于普通二叉搜索树的O(n)级别,有着显著的优势。

二、平衡二叉树的性质1. 每个节点的左子树和右子树的高度差不超过1。

2. 左子树和右子树都是平衡二叉树。

3. 平衡二叉树的节点数与其高度呈指数关系,即节点数为2^h-1。

三、平衡二叉树的实现与操作平衡二叉树的实现主要涉及以下几个操作:插入节点、删除节点、搜索节点等。

1. 插入节点:平衡二叉树在插入节点时,会维护每个节点的平衡因子(Balance Factor),即左子树高度减去右子树高度的值。

当插入节点后,如果某个节点的平衡因子超过1或小于-1,则需要进行相应的调整,使得平衡二叉树重新保持平衡。

2. 删除节点:删除节点涉及到调整平衡因子的问题。

当删除节点后,可能会破坏平衡二叉树的平衡性质。

需要通过旋转操作来重新调整平衡。

3. 搜索节点:与普通二叉搜索树相似,平衡二叉树的搜索操作也是通过比较节点值进行递归搜索的。

由于树的平衡性质,搜索操作的时间复杂度始终保持在O(logn)级别。

四、平衡二叉树的应用平衡二叉树的高效性使其在很多领域得到广泛应用。

以下是平衡二叉树的几个应用场景:1. 数据库索引:数据库中的索引通常采用平衡二叉树实现,可以提高数据检索的效率。

2. 数据的排序:平衡二叉树能够快速地对数据进行排序,例如,在多个关键字的排序中,通过构建平衡二叉树,可以依次按照关键字进行排序。

3. 自动补全:在搜索引擎和代码编辑器等应用中,平衡二叉树可以用于实现自动补全功能,根据用户的输入,快速匹配可能的补全结果。

Java中AVL平衡二叉树实现Map (仿照TreeMap和TreeSet)

Java中AVL平衡二叉树实现Map (仿照TreeMap和TreeSet)

Java中A VL平衡二叉树实现Map (仿照TreeMap和TreeSet)1、下面是AVLTreeMap的实现package com;import java.io.IOException;import java.util.*;public class AVLTreeMap<K, V> extends AbstractMap<K, V> implements NavigableMap<K, V>, java.io.Serializable {private static final long serialVersionUID = 1731396135957583906L;private final Comparator<? super K> comparator;private transient Entry<K, V> root = null;private transient int size = 0;private transient int modCount = 0;public AVLTreeMap() {comparator = null;}public AVLTreeMap(Comparator<? super K> comparator) {parator = comparator;}public AVLTreeMap(Map<? extends K, ? extends V> m) {comparator = null;putAll(m);}public AVLTreeMap(SortedMap<K, ? extends V> m) {comparator = parator();try {buildFromSorted(m.size(), m.entrySet().iterator(), null, null);} catch (IOException e) {} catch (ClassNotFoundException e) {}}public int size() {return size;}public boolean containsKey(Object key) {return getEntry(key) != null;}public boolean containsValue(Object value) {for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) {if (valEquals(value, e.value))return true;}return false;}public V get(Object key) {Entry<K, V> p = getEntry(key);return p == null ? null : p.value;}public Comparator<? super K> comparator() {return comparator;}public K firstKey() {return key(getFirstEntry());}public K lastKey() {return key(getLastEntry());}@SuppressWarnings({ "rawtypes", "unchecked" })public void putAll(Map<? extends K, ? extends V> map) {int mapSize = map.size();if (size == 0 && mapSize != 0 && map instanceof SortedMap) {Comparable<? super K> cmp = (Comparable<? super K>) ((SortedMap) map).comparator();if (cmp == comparator || (cmp != null && cmp.equals(comparator))) {++modCount;try {buildFromSorted(mapSize, map.entrySet().iterator(), null, null);} catch (IOException e) {} catch (ClassNotFoundException e) {}return;}}super.putAll(map);}@SuppressWarnings("unchecked")final Entry<K, V> getEntry(Object key) {if (comparator != null) {return getEntryUsingComparator(key);}if (key == null)throw new NullPointerException();Comparable<? super K> k = (Comparable<? super K>) key;Entry<K, V> p = root;while (p != null) {int cmp = pareTo(p.key);if (cmp < 0) {p = p.left;} else if (cmp > 0) {p = p.right;} else {return p;}}return null;}@SuppressWarnings("unchecked")final Entry<K, V> getEntryUsingComparator(Object key) { K k = (K) key;Comparator<? super K> cpr = comparator;if (cpr != null) {Entry<K, V> p = root;while (p != null) {int cmp = pare(k, p.key);if (cmp < 0)p = p.left;else if (cmp > 0)p = p.right;elsereturn p;}}return null;}final Entry<K, V> getCeilingEntry(Object key) {Entry<K, V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp < 0) {if (p.left != null)p = p.left;elsereturn p;} else if (cmp < 0) {if (p.right != null)p = p.right;else {Entry<K, V> parent = p.parent;Entry<K, V> ch = p;while (parent != null && ch == parent.right) {ch = parent;parent = parent.parent;}return parent;}} else {return p;}}return null;}final Entry<K, V> getFloorEntry(Object key) {Entry<K, V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp > 0) {if (p.right != null)p = p.right;elsereturn p;} else if (cmp < 0) {if (p.left != null)p = p.left;else {Entry<K, V> parent = p.parent;Entry<K, V> ch = p;while (parent != null && ch == parent.left) {ch = parent;parent = parent.parent;}return parent;}} else {return p;}}return null;}final Entry<K, V> getHigherEntry(Object key) {Entry<K, V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp < 0) {if (p.left != null)p = p.left;elsereturn p;} else {if (p.right != null)p = p.right;else {Entry<K, V> parent = p.parent;Entry<K, V> ch = p;while (parent != null && ch == parent.right) {ch = parent;parent = parent.parent;}return parent;}}}return null;}final Entry<K, V> getLowerEntry(Object key) {Entry<K, V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp > 0) {if (p.right != null)p = p.right;elsereturn p;} else {if (p.left != null)p = p.left;else {Entry<K, V> parent = p.parent;Entry<K, V> ch = p;while (parent != null && ch == parent.left) {ch = parent;parent = parent.parent;}return parent;}}}return null;}@SuppressWarnings("unchecked")public V put(K key, V value) {Entry<K, V> t = root;if (t == null) {root = new Entry<K, V>(key, value, null);root.height = 1;size++;modCount++;return null;}int cmp;Entry<K, V> parent;Comparator<? super K> cpr = comparator;if (cpr != null) {do {parent = t;cmp = pare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);} else {do {parent = t;cmp = ((Comparable<? super K>) key).compareTo(t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}Entry<K, V> e = new Entry<K, V>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.right = e;fixAfterInsertion(e);size++;modCount++;return null;}public V remove(Object key) {Entry<K, V> p = getEntry(key);if (p == null) {return null;}V oldVal = p.value;deleteEntry(p);return oldVal;}public void clear() {size = 0;modCount++;root = null;}@SuppressWarnings("unchecked")public Object clone() {AVLTreeMap<K, V> clone = null;try {clone = (AVLTreeMap<K, V>) super.clone();} catch (CloneNotSupportedException e) {throw new InternalError();}clone.root = null;clone.size = 0;clone.modCount = 0;clone.entrySet = null;clone.keySet = null;clone.descendingMap = null;try {clone.buildFromSorted(size, entrySet().iterator(), null, null);} catch (IOException e) {} catch (ClassNotFoundException e) {}return clone;}public Map.Entry<K, V> firstEntry() {return exportEntry(getFirstEntry());}public Map.Entry<K, V> lastEntry() {return exportEntry(getLastEntry());}public Map.Entry<K, V> pollFirstEntry() {AVLTreeMap.Entry<K, V> p = getFirstEntry();Map.Entry<K, V> result = exportEntry(p);if (p != null)deleteEntry(p);return result;}public Map.Entry<K, V> pollLastEntry() {AVLTreeMap.Entry<K, V> e = getLastEntry();Map.Entry<K, V> result = exportEntry(e);if (e != null)deleteEntry(e);return result;}public Map.Entry<K, V> lowerEntry(K key) {return exportEntry(getLowerEntry(key));}public K lowerKey(K key) {return keyOrNull(getLowerEntry(key));}public Map.Entry<K, V> floorEntry(K key) {return exportEntry(getFloorEntry(key));}public K floorKey(K key) {return keyOrNull(getFloorEntry(key));}public Map.Entry<K, V> ceilingEntry(K key) {return exportEntry(getCeilingEntry(key));}public K ceilingKey(K key) {return keyOrNull(getCeilingEntry(key));}public Map.Entry<K, V> higherEntry(K key) {return exportEntry(getHigherEntry(key));}public K higherKey(K key) {return keyOrNull(getHigherEntry(key));}private transient EntrySet entrySet = null;private transient KeySet<K> navigableKeySet = null;private transient NavigableMap<K, V> descendingMap = null; @SuppressWarnings("unused")private transient Set<K> keySet = null;private transient Collection<V> values = null;public Set<K> keySet() {return navigableKeySet();}@SuppressWarnings({ "unchecked", "rawtypes" })public NavigableSet<K> navigableKeySet() {KeySet<K> ks = navigableKeySet;return (ks != null) ? ks : (navigableKeySet = new KeySet(this));}public NavigableSet<K> descendingKeySet() {return descendingMap().navigableKeySet();}public Set<Map.Entry<K, V>> entrySet() {EntrySet es = entrySet;return (es != null) ? es : (entrySet = new EntrySet());}public Collection<V> values() {Collection<V> vs = values;return (vs != null) ? vs : (values = new Values());}@SuppressWarnings({ "unchecked", "rawtypes" })public NavigableMap<K, V> descendingMap() {NavigableMap<K, V> km = descendingMap;return (km != null) ? km : (descendingMap = new DescendingSubMap(this, true, null, true, true, null, true));}@SuppressWarnings({ "unchecked", "rawtypes" })public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {return new AscendingSubMap(this, false, fromKey, fromInclusive, false, toKey, toInclusive);}@SuppressWarnings({ "unchecked", "rawtypes" })public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {return new AscendingSubMap(this, true, null, true, false, toKey, inclusive);}@SuppressWarnings({ "unchecked", "rawtypes" })public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {return new AscendingSubMap(this, false, fromKey, inclusive, true, null, true);}public SortedMap<K, V> subMap(K fromKey, K toKey) {return subMap(fromKey, true, toKey, false);}public SortedMap<K, V> headMap(K toKey) {return headMap(toKey, false);}public SortedMap<K, V> tailMap(K fromKey) {return tailMap(fromKey, true);}class Values extends AbstractCollection<V> {public Iterator<V> iterator() {return new ValueIterator(getFirstEntry());}public int size() {return AVLTreeMap.this.size();}public boolean contains(Object o) {return AVLTreeMap.this.containsValue(o);}public boolean remove(Object o) {for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) { if (valEquals(o, e.value)) {deleteEntry(e);return true;}}return false;}public void clear() {AVLTreeMap.this.clear();}}class EntrySet extends AbstractSet<Map.Entry<K, V>> {public Iterator<Map.Entry<K, V>> iterator() {return new EntryIterator(getFirstEntry());}public int size() {return AVLTreeMap.this.size();}@SuppressWarnings("unchecked")public boolean contains(Object o) {if (!(o instanceof Map.Entry)) {return false;}Map.Entry<K, V> entry = (Map.Entry<K, V>) o;V value = entry.getValue();Entry<K, V> p = getEntry(entry.getKey());return p != null && valEquals(p.getValue(), value);}@SuppressWarnings("unchecked")public boolean remove(Object o) {if (!(o instanceof Map.Entry)) {return false;}Map.Entry<K, V> entry = (Map.Entry<K, V>) o;V value = entry.getValue();Entry<K, V> p = getEntry(entry.getKey());if (p != null && valEquals(p.getValue(), value)) {deleteEntry(p);return true;}return false;}public void clear() {AVLTreeMap.this.clear();}}Iterator<K> keyIterator() {return new KeyIterator(getFirstEntry());}Iterator<K> descendingKeyIterator() {return new DescendingKeyIterator(getLastEntry());}static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { private final NavigableMap<E, Object> m;KeySet(NavigableMap<E, Object> m) {this.m = m;}@SuppressWarnings({ "unchecked", "rawtypes" })public Iterator<E> iterator() {if (m instanceof AVLTreeMap)return ((AVLTreeMap) m).keyIterator();elsereturn (Iterator<E>) (((AVLTreeMap.NavigableSubMap) m).keyIterator());}@SuppressWarnings({ "unchecked", "rawtypes" })public Iterator<E> descendingIterator() {if (m instanceof AVLTreeMap)return ((AVLTreeMap) m).descendingKeyIterator();elsereturn (Iterator<E>) (((AVLTreeMap.NavigableSubMap)m).descendingKeyIterator());}public int size() {return m.size();}public boolean isEmpty() {return m.isEmpty();}public boolean contains(Object o) {return m.containsKey(o);}public void clear() {m.clear();}public E lower(E e) {return m.lowerKey(e);}public E floor(E e) {return m.floorKey(e);}public E ceiling(E e) {return m.ceilingKey(e);}public E higher(E e) {return m.higherKey(e);}public E first() {return m.firstKey();}public E last() {return stKey();}public Comparator<? super E> comparator() {return parator();}public E pollFirst() {Map.Entry<E, Object> e = m.pollFirstEntry();return e == null ? null : e.getKey();}public E pollLast() {Map.Entry<E, Object> e = m.pollLastEntry();return e == null ? null : e.getKey();}public boolean remove(Object o) {int oldSize = m.size();m.remove(o);return oldSize != m.size();}public NavigableSet<E> descendingSet() {return new AVLTreeSet<E>(m.descendingMap());}public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {return new AVLTreeSet<E>(m.subMap(fromElement, fromInclusive, toElement, toInclusive));}public NavigableSet<E> headSet(E toElement, boolean inclusive) {return new AVLTreeSet<E>(m.headMap(toElement, inclusive));}public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {return new AVLTreeSet<E>(m.tailMap(fromElement, inclusive));}public SortedSet<E> subSet(E fromElement, E toElement) {return subSet(fromElement, true, toElement, false);}public SortedSet<E> headSet(E toElement) {return headSet(toElement, false);}public SortedSet<E> tailSet(E fromElement) {return tailSet(fromElement, true);}}abstract class PrivateEntryIterator<T> implements Iterator<T> {Entry<K, V> next;Entry<K, V> lastReturned;int expectedModCount;PrivateEntryIterator(Entry<K, V> first) {expectedModCount = modCount;lastReturned = null;next = first;}public final boolean hasNext() {return next != null;}final Entry<K, V> nextEntry() {Entry<K, V> e = next;if (next == null)throw new NoSuchElementException();if (modCount != expectedModCount)throw new ConcurrentModificationException();next = successor(e);lastReturned = e;return e;}final Entry<K, V> prevEntry() {Entry<K, V> e = next;if (next == null)throw new NoSuchElementException();if (modCount != expectedModCount)throw new ConcurrentModificationException();next = predecessor(e);lastReturned = e;return e;}public void remove() {if (lastReturned == null)throw new IllegalStateException();if (modCount != expectedModCount)throw new ConcurrentModificationException();if (leftOf(lastReturned) != null && rightOf(lastReturned) != null) next = lastReturned;deleteEntry(lastReturned);expectedModCount = modCount;lastReturned = null;}}final class EntryIterator extends PrivateEntryIterator<Map.Entry<K, V>> { EntryIterator(Entry<K, V> first) {super(first);}public Map.Entry<K, V> next() {return nextEntry();}}final class ValueIterator extends PrivateEntryIterator<V> {ValueIterator(Entry<K, V> first) {super(first);}public V next() {return nextEntry().value;}}final class KeyIterator extends PrivateEntryIterator<K> {KeyIterator(Entry<K, V> first) {super(first);}public K next() {return nextEntry().key;}}final class DescendingKeyIterator extends PrivateEntryIterator<K> {DescendingKeyIterator(Entry<K, V> first) {super(first);}public K next() {return prevEntry().key;}}@SuppressWarnings("unchecked")final int compare(Object k1, Object k2) {return comparator == null ? ((Comparable<? super K>) k1).compareTo((K) k2) : pare((K) k1, (K) k2);}final static boolean valEquals(Object o1, Object o2) {return o1 == null ? o2 == null : o1.equals(o2);}@SuppressWarnings({ "unchecked", "rawtypes" })static <K, V> Map.Entry<K, V> exportEntry(Entry<K, V> e) {return e == null ? null : new AbstractMap.SimpleImmutableEntry(e);}static <K, V> K keyOrNull(Entry<K, V> e) {return e == null ? null : e.key;}static <K, V> K key(Entry<K, V> e) {if (e == null)throw new NoSuchElementException();return e.key;}final int max(int height1, int height2) {return (height1 > height2) ? height1 : height2;}static abstract class NavigableSubMap<K, V> extends AbstractMap<K, V> implements NavigableMap<K, V>, java.io.Serializable {private static final long serialVersionUID = 3330238317193227055L;final AVLTreeMap<K, V> m;final K lo, hi;final boolean fromStart, toEnd;final boolean loInclusive, hiInclusive;NavigableSubMap(AVLTreeMap<K, V> m, boolean fromStart, K lo, boolean loInclusive, boolean toEnd, K hi, boolean hiInclusive) {if (!fromStart && !toEnd) {if (pare(lo, hi) > 0)throw new IllegalArgumentException("fromKey > toKey");} else {if (!fromStart)pare(lo, lo);elsepare(hi, hi);}this.m = m;this.lo = lo;this.hi = hi;this.fromStart = fromStart;this.toEnd = toEnd;this.loInclusive = loInclusive;this.hiInclusive = hiInclusive;}final boolean tooLow(Object key) {if (!fromStart) {int c = pare(key, lo);if (c < 0 || (c == 0 && !loInclusive))return true;}return false;}final boolean tooHigh(Object key) {if (!toEnd) {int c = pare(key, hi);if (c > 0 || (c == 0 && !hiInclusive))return true;}return false;}final boolean inRange(Object key) {return !tooLow(key) && !tooHigh(key);}final boolean inClosedRange(Object key) {return (fromStart || pare(key, lo) >= 0) && (toEnd || pare(key, hi) <= 0);}final boolean inRange(Object key, boolean inclusive) {return inclusive ? inRange(key) : inClosedRange(key);}final AVLTreeMap.Entry<K, V> absLowest() {AVLTreeMap.Entry<K, V> e = fromStart ? m.getFirstEntry() : (loInclusive ?m.getCeilingEntry(lo) : m.getHigherEntry(lo));return (e == null || tooHigh(e.key)) ? null : e;}final AVLTreeMap.Entry<K, V> absHighest() {AVLTreeMap.Entry<K, V> e = toEnd ? m.getLastEntry() : (hiInclusive ?m.getFloorEntry(hi) : m.getLowerEntry(hi));return (e == null || tooLow(e.key) ? null : e);}final AVLTreeMap.Entry<K, V> absCeiling(K key) {if (tooLow(key))return absLowest();AVLTreeMap.Entry<K, V> e = m.getCeilingEntry(key);return (e == null || tooHigh(e.key)) ? null : e;}final AVLTreeMap.Entry<K, V> absHigher(K key) {if (tooLow(key))return absLowest();AVLTreeMap.Entry<K, V> e = m.getHigherEntry(key);return (e == null || tooHigh(e.key)) ? null : e;}final AVLTreeMap.Entry<K, V> absFloor(K key) {if (tooHigh(key))return absHighest();AVLTreeMap.Entry<K, V> e = m.getFloorEntry(key);return (e == null || tooLow(e.key)) ? null : e;}final AVLTreeMap.Entry<K, V> absLower(K key) {if (tooHigh(key))return absHighest();AVLTreeMap.Entry<K, V> e = m.getLowerEntry(key);return (e == null || tooLow(e.key)) ? null : e;}final AVLTreeMap.Entry<K, V> absHighFence() {return toEnd ? null : (hiInclusive ? m.getHigherEntry(hi) : m.getCeilingEntry(hi));}final AVLTreeMap.Entry<K, V> absLowFence() {return fromStart ? null : (loInclusive ? m.getLowerEntry(lo) :m.getCeilingEntry(lo));}abstract AVLTreeMap.Entry<K, V> subLowest();abstract AVLTreeMap.Entry<K, V> subHighest();abstract AVLTreeMap.Entry<K, V> subCeiling(K key);abstract AVLTreeMap.Entry<K, V> subHigher(K key);abstract AVLTreeMap.Entry<K, V> subFloor(K key);abstract AVLTreeMap.Entry<K, V> subLower(K key);abstract Iterator<K> keyIterator();abstract Iterator<K> descendingKeyIterator();public boolean isEmpty() {return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty(); }public int size() {return (fromStart && toEnd) ? m.size() : entrySet().size();}public final boolean containsKey(Object key) {return inRange(key) && m.containsKey(key);}public final V put(K key, V value) {if (!inRange(key))throw new IllegalArgumentException("key out of range");return m.put(key, value);}public final V get(Object key) {return !inRange(key) ? null : m.get(key);}public final V remove(Object key) {return !inRange(key) ? null : m.remove(key);}public Map.Entry<K, V> ceilingEntry(K key) {return exportEntry(subCeiling(key));}public K ceilingKey(K key) {return keyOrNull(subCeiling(key));}public Map.Entry<K, V> higherEntry(K key) {return exportEntry(subHigher(key));}public K higherKey(K key) {return keyOrNull(subHigher(key));}public Map.Entry<K, V> floorEntry(K key) { return exportEntry(subFloor(key));}public K floorKey(K key) {return keyOrNull(subFloor(key));}public Map.Entry<K, V> lowerEntry(K key) { return exportEntry(subLower(key));}public K lowerKey(K key) {return keyOrNull(subLower(key));}public K firstKey() {return key(subLowest());}public K lastKey() {return key(subHighest());}public Map.Entry<K, V> firstEntry() {return exportEntry(subLowest());}public Map.Entry<K, V> lastEntry() {return exportEntry(subHighest());}public Map.Entry<K, V> pollFirstEntry() { AVLTreeMap.Entry<K, V> e = subLowest();Map.Entry<K, V> result = exportEntry(e);if (e != null)m.deleteEntry(e);return result;}public Map.Entry<K, V> pollLastEntry() { AVLTreeMap.Entry<K, V> e = subHighest();Map.Entry<K, V> result = exportEntry(e);if (e != null)m.deleteEntry(e);return result;}transient NavigableMap<K, V> descendingMapView = null;transient EntrySetView entrySetView = null;transient KeySet<K> navigableKeySetView = null;@SuppressWarnings({ "unchecked", "rawtypes" })public final NavigableSet<K> navigableKeySet() {KeySet<K> nksv = navigableKeySetView;return nksv != null ? nksv : (navigableKeySetView = new AVLTreeMap.KeySet(this));}public final Set<K> keySet() {return navigableKeySet();}public NavigableSet<K> descendingKeySet() {return descendingMap().navigableKeySet();}public SortedMap<K, V> subMap(K fromKey, K toKey) {return subMap(fromKey, true, toKey, false);}public SortedMap<K, V> headMap(K toKey) {return headMap(toKey, false);}public SortedMap<K, V> tailMap(K fromKey) {return tailMap(fromKey, true);}abstract class EntrySetView extends AbstractSet<Map.Entry<K, V>> { private transient int size = -1, sizeModCount;public int size() {if (fromStart && toEnd)return m.size();if (size == -1 || sizeModCount != m.modCount) {size = 0;Iterator<Map.Entry<K, V>> i = iterator();while (i.hasNext()) {size++;i.next();}}return size;}public boolean isEmpty() {AVLTreeMap.Entry<K, V> e = absLowest();return (e == null || tooHigh(e));}@SuppressWarnings("unchecked")public boolean contains(Object o) {if (!(o instanceof Map.Entry))return false;Map.Entry<K, V> entry = (Map.Entry<K, V>) o;K key = entry.getKey();if (!inRange(key))return false;AVLTreeMap.Entry<K, V> node = m.getEntry(key);return node != null && valEquals(node.getValue(), entry.getValue());}@SuppressWarnings("unchecked")public boolean remove(Object o) {if (!(o instanceof Map.Entry))return false;Map.Entry<K, V> entry = (Map.Entry<K, V>) o;K key = entry.getKey();if (!inRange(key))return false;AVLTreeMap.Entry<K, V> node = m.getEntry(key);if (node != null && valEquals(node.getValue(), entry.getValue())) { m.deleteEntry(node);return true;}return false;}}abstract class SubMapIterator<T> implements Iterator<T> {AVLTreeMap.Entry<K, V> lastReturned;AVLTreeMap.Entry<K, V> next;final K fenceKey;int expectedModCount;SubMapIterator(AVLTreeMap.Entry<K, V> first, AVLTreeMap.Entry<K, V> fence) {expectedModCount = m.modCount;lastReturned = null;next = first;fenceKey = (fence == null ? null : fence.key);}public boolean hasNext() {return (next != null) && (next.key != fenceKey);}final AVLTreeMap.Entry<K, V> nextEntry() {AVLTreeMap.Entry<K, V> e = next;if (next == null)throw new NoSuchElementException();if (expectedModCount != m.modCount)throw new ConcurrentModificationException();next = successor(e);lastReturned = e;return e;}final AVLTreeMap.Entry<K, V> prevEntry() {AVLTreeMap.Entry<K, V> e = next;if (next == null)throw new NoSuchElementException();if (expectedModCount != m.modCount)throw new ConcurrentModificationException();next = predecessor(e);lastReturned = e;return e;}final void removeAscending() {if (lastReturned == null)throw new IllegalStateException();if (expectedModCount != m.modCount)throw new ConcurrentModificationException();if (lastReturned.left != null && lastReturned.right != null)next = lastReturned;m.deleteEntry(lastReturned);lastReturned = null;expectedModCount = m.modCount;}final void removeDescending() {if (lastReturned == null)throw new IllegalStateException();if (expectedModCount != m.modCount)throw new ConcurrentModificationException();m.deleteEntry(lastReturned);lastReturned = null;expectedModCount = m.modCount;}}final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K, V>> { SubMapEntryIterator(AVLTreeMap.Entry<K, V> first, AVLTreeMap.Entry<K, V> fence) {super(first, fence);}public Map.Entry<K, V> next() {return nextEntry();}public void remove() {removeAscending();}}final class SubMapKeyIterator extends SubMapIterator<K> {SubMapKeyIterator(AVLTreeMap.Entry<K, V> first, AVLTreeMap.Entry<K, V> fence) {super(first, fence);}public K next() {return nextEntry().key;}。

平衡二叉树实现代码

平衡二叉树实现代码

平衡二叉树实现代码平衡二叉树(Balanced Binary Tree),也叫 AVL 树,是一种特殊的二叉树,它的每个节点的左子树和右子树的高度差不超过1、当插入或删除一个节点后,如果导致树的不平衡,就通过旋转操作来恢复平衡。

下面是平衡二叉树的实现代码:```python#定义平衡二叉树的节点类class AVLNode:def __init__(self, key):self.key = keyself.left = Noneself.right = Noneself.height = 1#定义平衡二叉树类class AVLTree:def __init__(self):self.root = None#获取节点的高度def get_height(self, node):if node is None:return 0return node.height#计算平衡因子def get_balance(self, node):if node is None:return 0return self.get_height(node.left) -self.get_height(node.right)#左旋操作def left_rotate(self, z):y = z.rightT2 = y.lefty.left = zz.right = T2z.height = 1 + max(self.get_height(z.left), self.get_height(z.right))y.height = 1 + max(self.get_height(y.left), self.get_height(y.right))return y#右旋操作def right_rotate(self, z):y = z.leftT3 = y.righty.right = zz.left = T3z.height = 1 + max(self.get_height(z.left), self.get_height(z.right))y.height = 1 + max(self.get_height(y.left), self.get_height(y.right))return y#插入节点def insert(self, key):def insert_node(node, key):if node is None:return AVLNode(key)elif key < node.key:node.left = insert_node(node.left, key)else:node.right = insert_node(node.right, key)node.height = 1 + max(self.get_height(node.left), self.get_height(node.right))balance = self.get_balance(node)#如果节点不平衡,进行旋转操作来恢复平衡if balance > 1:if key < node.left.key:return self.right_rotate(node)else:node.left = self.left_rotate(node.left)return self.right_rotate(node)if balance < -1:if key > node.right.key:return self.left_rotate(node)else:node.right = self.right_rotate(node.right)return self.left_rotate(node)return nodeself.root = insert_node(self.root, key)#删除节点def delete(self, key):def delete_node(node, key):if node is None:return nodeelif key < node.key:node.left = delete_node(node.left, key) elif key > node.key:node.right = delete_node(node.right, key) else:if node.left is None:temp = node.rightnode = Nonereturn tempelif node.right is None:temp = node.leftnode = Nonereturn temptemp = self.get_min_value_node(node.right)node.key = temp.keynode.right = delete_node(node.right, temp.key)if node is None:return nodenode.height = 1 + max(self.get_height(node.left), self.get_height(node.right))balance = self.get_balance(node)#如果节点不平衡,进行旋转操作来恢复平衡if balance > 1:if self.get_balance(node.left) >= 0:return self.right_rotate(node)else:node.left = self.left_rotate(node.left)return self.right_rotate(node)if balance < -1:if self.get_balance(node.right) <= 0:return self.left_rotate(node)else:node.right = self.right_rotate(node.right)return self.left_rotate(node)return nodeself.root = delete_node(self.root, key) #获取以一些节点为根的子树中的最小值节点def get_min_value_node(self, node):if node is None or node.left is None: return nodereturn self.get_min_value_node(node.left) #中序遍历树def inorder_traversal(self):def inorder(node):if node is None:returninorder(node.left)print(node.key, end=" ")inorder(node.right)inorder(self.root)#测试代码if __name__ == '__main__':tree = AVLTreenodes = [50, 30, 70, 20, 40, 60, 80, 25, 10, 55]for node in nodes:tree.insert(node)print("平衡二叉树中序遍历结果:")tree.inorder_traversalprint("\n删除节点 40 后的平衡二叉树中序遍历结果:")tree.delete(40)tree.inorder_traversal```以上就是平衡二叉树的实现代码,代码中包含了平衡二叉树节点类的定义,以及插入节点、删除节点、左旋和右旋操作等方法的实现。

平衡二叉树的实现c语言

平衡二叉树的实现c语言

平衡二叉树的实现c语言平衡二叉树(AVL树)是一种自平衡的二叉查找树,其中任何节点的两个子树的高度差最多为1。

下面是一个简单的AVL树的C语言实现:```cinclude <>include <>typedef struct AVLNode {int key;int height;struct AVLNode left, right;} AVLNode;typedef struct {AVLNode root;} AVLTree;int getHeight(AVLNode node) {if (node == NULL)return 0;return node->height;}int getBalance(AVLNode node) {if (node == NULL)return 0;return getHeight(node->left) - getHeight(node->right);}AVLNode rotateRight(AVLNode y) {AVLNode x = y->left;AVLNode T2 = x->right;x->right = y;y->left = T2;y->height = max(getHeight(y->left), getHeight(y->right)) + 1; x->height = max(getHeight(x->left), getHeight(x->right)) + 1; return x; // new root is x}AVLNode rotateLeft(AVLNode x) {AVLNode y = x->right;AVLNode T2 = y->left;y->left = x;x->right = T2;x->height = max(getHeight(x->left), getHeight(x->right)) + 1; y->height = max(getHeight(y->left), getHeight(y->right)) + 1; return y; // new root is y}AVLNode insert(AVLTree tree, int key) {AVLNode root = tree->root;if (root == NULL) { // tree is empty, create a new node as root. tree->root = (AVLNode)malloc(sizeof(AVLNode));root = tree->root;root->key = key;root->height = 1;return root;} else if (key < root->key) { // insert into left subtree.root->left = insert(root->left, key);} else if (key > root->key) { // insert into right subtree.root->right = insert(root->right, key);} else { // duplicate keys not allowed.return root; // don't insert duplicate key.}root->height = 1 + max(getHeight(root->left), getHeight(root->right)); // adjust height of current node.int balance = getBalance(root);if (balance > 1 && key < root->left->key) { // left left case.return rotateRight(root); // rotate right.} else if (balance < -1 && key > root->right->key) { // right right case.return rotateLeft(root); // rotate left.} else if (balance > 1 && key > root->left->key) { // left right case. root->left = rotateLeft(root->left); // rotate left first.return rotateRight(root); // then rotate right.} else if (balance < -1 && key < root->right->key) { // right left case.root->right = rotateRight(root->right); // rotate right first.return rotateLeft(root); // then rotate left.} // keep balance.return root; // already balanced.} ```。

算法导论AVL树

算法导论AVL树

算法导论思考题P177:13-3:AVL树主要思路:实现AVL树的关键在于维持树的平衡性。

为了保证平衡,AVL树中的每个结点都有一个平衡因子,它表示这个结点的左、右子树的高度差,也就是左子树的高度减去右子树的高度的结果值。

AVL树上所有结点的平衡因子bal值只能是-1、0、1。

反之,只要二叉树上一个结点的bal的绝对值大于1,则该二叉树就不是平衡二叉树。

每当插入一个节点或删除都有可能破坏了树的平衡性。

因此首先检查是否破坏了树的平衡性,如果因插入结点而破坏了二叉查找树的平衡,则找出离插入点最近的不平衡结点,然后将该不平衡结点为根的子树进行旋转操作,称该不平衡结点为旋转根,以该旋转根为根的子树称为最小不平衡子树。

要对树进行翻转,以满足平衡性。

翻转使用的方法是红黑树中提到的左旋和右旋。

根据出现的不同情况对树进行旋转。

归纳为4种旋转类型:LL型旋转、RR型旋转、LR型旋转、RL型旋转。

1、LL型旋转:2、LR型旋转:3、RR型旋转:4、RL 型旋转:上图(a )(b )(c )(d )为四种类型的旋转图示。

证明:假设h N 是一颗高度为h 的AVL 树中最小的节点数:1,0,11021==++=--N N N N N h h h可以看到h N 的定义与斐波那契数列的定义非常相似1,0,1021==+=--F F F F F h h h利用归纳法证明:当0≥h 时12-=+h h F N ,而5/h h F ϕ≈(其中251+=ϕ),则15/2-=+h h N ϕ。

反之,含有n 个结点的平衡树的最大深度为)(log )2(log 44.1~2))1(5(log 2n O n n =+-+ϕ。

在平衡的的平衡二叉查找树Balanced BST 上插入一个新的数据元素e 的递归算法可描述如下:(1)若BBST 为空树,则插入一个数据元素为e 的新结点作为BBST 的根结点,树的深度增1;(2)若e 的关键字和BBST 的根结点的关键字相等,则不进行;(3)若e 的关键字小于BBST 的根结点的关键字,而且在BBST 的左子树中不存在和e 有相同关键字的结点,则将e 插入在BBST 的左子树上,并且当插入之后的左子树深度增加(+1)时,分别就下列不同情况处理之:a 、BBST 的根结点的平衡因子为-1(右子树的深度大于左子树的深度,则将根结点的平衡因子更改为0,BBST 的深度不变;b 、BBST 的根结点的平衡因子为0(左、右子树的深度相等):则将根结点的平衡因子更改为1,BBST 的深度增1;c 、BBST 的根结点的平衡因子为1(左子树的深度大于右子树的深度):若BBST 的左子树根结点的平衡因子为1:则需进行单向右旋平衡处理,并且在右旋处理之后,将根结点和其右子树根结点的平衡因子更改为0,树的深度不变;(4)若e的关键字大于BBST的根结点的关键字,而且在BBST的右子树中不存在和e有相同关键字的结点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加(+1)时,分别就不同情况处理之。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

typedef struct AVLTreeNode *AVLTree;
typedef struct AVLTreeNode{
ElementType Data;
AVLTree Left;
AVLTree Right;
int Height;
};
AVLTree AVL_Insertion ( ElementType X, AVLTree T )
{ /* 将X插入AVL树T中,并且返回调整后的AVL树*/ if ( !T ) { /* 若插入空树,则新建包含一个结点的树*/ T = (AVLTree)malloc(sizeof(struct AVLTreeNode));
T->Data = X;
T->Height = 0;
T->Left = T->Right = NULL;
} /* if (插入空树) 结束*/
else if (X < T->Data) { /* 插入T的左子树*/
T->Left = AVL_Insertion(X, T->Left);
if (GetHeight(T->Left) - GetHeight(T->Right) == 2 )
/* 需要左旋*/
if (X < T->Left->Data)
T = SingleLeftRotation(T); /* 左单旋*/
else
T = DoubleLeftRightRotation(T); /* 左-右双旋*/ } /* else if (插入左子树) 结束*/
else if (X > T->Data) { /* 插入T的右子树*/
T->Right = AVL_Insertion(X, T->Right);
if (GetHeight(T->Left) - GetHeight(T->Right) == -2 )
/* 需要右旋*/
if (X > T->Right->Data)
T = SingleRightRotation(T); /* 右单旋*/
else
T = DoubleRightLeftRotation(T); /* 右-左双旋*/ } /* else if (插入右子树) 结束*/
/* else X == T->Data,无须插入*/
T->Height = Max(GetHeight(T->Left),GetHeight(T->Right))+1;
/*更新树高*/
return T;
}
AVLTree SingleLeftRotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B */
/* 将A与B做如图4.35所示的左单旋,更新A与B的高度,返回新的根结点B */
AVLTree B = A->Left;
A->Left = B->Right;
B->Right = A;
A->Height = Max(GetHeight(A->Left), GetHeight(A->Right))+1;
B->Height = Max(GetHeight(B->Left), A->Height)+1;
return B;
}
AVLTree DoubleLeftRightRotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
/* 将A、B与C做如图4.38所示的两次单旋,返回新的根结点C */
A->Left = SingleRightRotation(A->Left); /*将B与C做右单旋,C被返回*/
return SingleLeftRotation(A); /*将A与C做左单旋,C被返回*/
}。

相关文档
最新文档