亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

C語言數據結構之平衡二叉樹(AVL樹)實現方法示例

2020-01-26 13:47:33
字體:
來源:轉載
供稿:網友

本文實例講述了C語言數據結構之平衡二叉樹(AVL樹)實現方法。分享給大家供大家參考,具體如下:

AVL樹是每個結點的左子樹和右子樹的高度最多差1的二叉查找樹。

要維持這個樹,必須在插入和刪除的時候都檢測是否出現破壞樹結構的情況。然后立刻進行調整。

看了好久,網上各種各種的AVL樹,千奇百怪。

關鍵是要理解插入的時候旋轉的概念。

//// AvlTree.h// HelloWorld// Created by feiyin001 on 17/1/9.// Copyright (c) 2017年 FableGame. All rights reserved.//#ifndef __HelloWorld__AvlTree__#define __HelloWorld__AvlTree__#include <iostream>namespace Fable{  int max(int a, int b)  {    return a > b? a:b;  }  //二叉查找樹,對于Comparable,必須實現了><=的比較  template<typename Comparable>  class AvlTree  {  public:    //構造函數    AvlTree(){}    //復制構造函數    AvlTree(const AvlTree& rhs)    {      root = clone(rhs.root);    }    //析構函數    ~AvlTree()    {      makeEmpty(root);    }    //復制賦值運算符    const AvlTree& operator=(const AvlTree& rhs)    {      if (this != &rhs)      {        makeEmpty(root);//先清除        root = clone(rhs.root);//再復制      }      return *this;    }    //查找最小的對象    const Comparable& findMin()const    {      findMin(root);    }    //查找最大的對象    const Comparable& findMax()const    {      findMax(root);    }    //是否包含了某個對象    bool contains(const Comparable& x)const    {      return contains(x, root);    }    //樹為空    bool isEmpty()const    {      return root == nullptr;    }    //打印整棵樹    void printTree()const    {      printTree(root);    }    //清空樹    void makeEmpty()    {      makeEmpty(root);    }    //插入某個對象    void insert(const Comparable& x)    {      insert(x, root);    }    //移除某個對象    void remove(const Comparable& x)    {      remove(x, root);    }  private:    struct AvlNode    {      Comparable element;      AvlNode* left;      AvlNode* right;      int height;      AvlNode(const Comparable& theElement, AvlNode* lt, AvlNode* rt, int h = 0)      :element(theElement), left(lt), right(rt), height(h){}    };    typedef AvlNode* AvlNodePtr;    AvlNodePtr root;//根結點    //順時針旋轉    void clockwiseRotate(AvlNodePtr& a)    {      AvlNodePtr b = a->left;//左葉子      a->left = b->right;//a的左葉子變為b的右葉子,b本來的子結點都比a小的。      b->right = a;//b的右結點指向a,b的高度上升了。      a->height = max(height(a->left), height(a->right)) + 1;//重新計算a的高度      b->height = max(height(b->left), a->height) + 1;//重新計算b的高度      a = b;//a的位置現在是b,當前的根結點    }    //逆時針旋轉    void antiClockWiseRotate(AvlNodePtr& a)    {      AvlNodePtr b = a->right;//右結點      a->right = b->left;//a接收b的左結點      b->left = a;//自己成為b的左結點      a->height = max(height(a->left), height(a->right)) + 1;//計算高度      b->height = max(b->height, height(a->right)) + 1;//計算高度      a = b;//新的根結點    }    //對左邊結點的雙旋轉    void doubleWithLeftChild(AvlNodePtr& k3)    {      antiClockWiseRotate(k3->left);//逆時針旋轉左結點      clockwiseRotate(k3);//順時針旋轉自身    }    //對右邊結點的雙旋轉    void doubleWithRightChild(AvlNodePtr& k3)    {      clockwiseRotate(k3->right);//順時針旋轉有節點      antiClockWiseRotate(k3);//逆時針旋轉自身    }    //插入對象,這里使用了引用    void insert(const Comparable& x, AvlNodePtr& t)    {      if (!t)      {        t = new AvlNode(x, nullptr, nullptr);      }      else if (x < t->element)      {        insert(x, t->left);//比根結點小,插入左邊        if (height(t->left) - height(t->right) == 2)//高度差達到2了        {          if (x < t->left->element)//插入左邊          {            clockwiseRotate(t);//順時針旋轉          }          else          {            doubleWithLeftChild(t);//雙旋轉          }        }      }      else if (x > t->element)      {        insert(x, t->right);//比根結點大,插入右邊        if (height(t->right) - height(t->left) == 2)//高度差達到2        {          if (t->right->element < x)//插入右邊          {            antiClockWiseRotate(t);//旋轉          }          else          {            doubleWithRightChild(t);//雙旋轉          }        }      }      else      {        //相同的      }      t->height = max(height(t->left), height(t->right)) + 1;//計算結點的高度    }    void removeMin(AvlNodePtr& x, AvlNodePtr& t)const    {      if (!t)      {        return;//找不到      }      if (t->left)      {        removeMin(t->left);//使用了遞歸的方式      }      else      {        //找到最小的結點了        x->element = t->element;        AvlNodePtr oldNode = t;        t = t->right;        delete oldNode;//刪除原來要刪除的結點      }      if (t)      {        t->height = max(height(t->left), height(t->right)) + 1;//計算結點的高度        if(height(t->left) - height(t->right) == 2)        { //如果左兒子高度大于右兒子高度          if(height(t->left->left) >= height(t->left->right))//并且左兒子的左子樹高度大于左兒子的右子樹高度          {            clockwiseRotate(t); //順時針旋轉          }          else          {            doubleWithLeftChild(t);//雙旋轉左子樹          }        }        else        {          if(height(t->right->right) - height(t->right->left) == 2) //如果右子樹大于左子樹          {            antiClockWiseRotate(t);//逆時針旋轉          }          else          {            doubleWithRright(t);//雙旋轉右子樹          }        }      }    }    //刪除某個對象,這里必須要引用    void remove(const Comparable& x, AvlNodePtr& t)const    {      if (!t)      {        return;//樹為空      }      else if (x < t->element)      {        remove(x, t->left);//比根結點小,去左邊查找      }      else if (x > t->element)      {        remove(x, t->right);//比根結點大,去右邊查找      }      else if (!t->left && !t->right)//找到結點了,有兩個葉子      {        removeMin(t, t->right);//這里選擇的方法是刪除右子樹的最小的結點      }      else      {        AvlNodePtr oldNode = t;        t = (t->left) ? t->left : t->right;//走到這里,t最多只有一個葉子,將t指向這個葉子        delete oldNode;//刪除原來要刪除的結點      }      if (t)      {        t->height = max(height(t->left), height(t->right)) + 1;//計算結點的高度        if(height(t->left) - height(t->right) == 2)        { //如果左兒子高度大于右兒子高度          if(height(t->left->left) >= height(t->left->right))//并且左兒子的左子樹高度大于左兒子的右子樹高度          {            clockwiseRotate(t); //順時針旋轉          }          else          {            doubleWithLeftChild(t);//雙旋轉左子樹          }        }        else        {          if(height(t->right->right) - height(t->right->left) == 2) //如果右子樹大于左子樹          {            antiClockWiseRotate(t);//逆時針旋轉          }          else          {            doubleWithRright(t);//雙旋轉右子樹          }        }      }    }    //左邊子樹的結點肯定比當前根小的,所以一直往左邊尋找    AvlNodePtr findMin(AvlNodePtr t)const    {      if (!t)      {        return nullptr;//找不到      }      if (!t->left)      {        return t;      }      return findMin(t->left);//使用了遞歸的方式    }    //右邊子樹的結點肯定比當前根大,所以一直往右邊找    AvlNodePtr findMax(AvlNodePtr t)const    {      if (t)      {        while (t->right)//使用了循環的方式        {          t = t->right;        }      }      return t;    }    //判斷是否包含某個對象,因為要使用遞歸,所以還有一個public版本的    bool contains(const Comparable& x, AvlNodePtr t)const    {      if (!t)      {        return false;//空結點了      }      else if (x < t->element)      {        //根據二叉樹的定義,比某個結點小的對象,肯定只能存在與這個結點的左邊的子樹        return contains(x, t->left);      }      else if (x > t->element)      {        //根據二叉樹的定義,比某個結點大的對象,肯定只能存在與這個結點的右邊的子樹        return contains(x, t->right);      }      else      {        //相等,就是找到啦。        return true;      }    }    //清空子樹    void makeEmpty(AvlNodePtr& t)    {      if (t)      {        makeEmpty(t->left);//清空左邊        makeEmpty(t->right);//清空右邊        delete t;//釋放自身      }      t = nullptr;//置為空    }    //打印子樹,這里沒有使用復雜的排位,純屬打印    void printTree(AvlNodePtr t)const    {      if (!t)      {        return;      }      std::cout << t->element << std::endl;//輸出自身的對象      printTree(t->left);//打印左子樹      printTree(t->right);//打印右子樹    }    AvlNodePtr clone(AvlNodePtr t)const    {      if (!t)      {        return nullptr;      }      return new AvlNode(t->element, clone(t->left), clone(t->right));    }    int height(AvlNodePtr t)const    {      return t == nullptr ? -1 : t->height;    }  };}#endif

簡單測試一下。

//// AvlTree.cpp// HelloWorld// Created by feiyin001 on 17/1/9.// Copyright (c) 2017年 FableGame. All rights reserved.//#include "AvlTree.h"using namespace Fable;int main(int argc, char* argv[]){  AvlTree<int> a;  for(int i = 0; i < 100; ++i)  {    a.insert(i);  }  return 0;}

這個刪除的方法完全是自己寫的,可能不是很高效。

希望本文所述對大家C語言程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品入口福利| 国产91精品久| 深夜福利91大全| 97在线免费视频| 91老司机精品视频| 亚洲国产黄色片| 欧美极品少妇xxxxⅹ喷水| 成人乱人伦精品视频在线观看| 日韩电视剧在线观看免费网站| 成人欧美在线观看| 欧美激情视频播放| 国产精品美女在线观看| 2019最新中文字幕| 久久久久久国产| 97视频在线免费观看| 国产欧美精品一区二区三区介绍| 欧美xxxx18国产| 全色精品综合影院| 亚洲精品v欧美精品v日韩精品| www.日韩系列| 亚洲视频电影图片偷拍一区| 日韩黄色高清视频| 欧美日韩亚洲激情| 成人久久久久久久| 成人网页在线免费观看| 日韩欧美国产黄色| 精品亚洲一区二区三区在线播放| 青青在线视频一区二区三区| 欧美成人h版在线观看| 色视频www在线播放国产成人| 亚洲第一区第二区| 久久精品国产电影| 日韩美女av在线| 日韩欧美中文字幕在线观看| 国产精品日韩在线观看| 中文字幕亚洲情99在线| 国产精品伦子伦免费视频| 欧美片一区二区三区| 亚洲精品乱码久久久久久金桔影视| 国产成人精品久久二区二区91| 日韩电影免费观看中文字幕| 日本久久久a级免费| 亚洲无限av看| 日韩欧美中文在线| 国产精品成人在线| 久久的精品视频| 国产热re99久久6国产精品| 亚洲白拍色综合图区| 成人精品在线观看| 欧美电影在线观看高清| 欧美高清视频一区二区| 国产一区二区丝袜高跟鞋图片| 91精品久久久久久久久久入口| 欧美中文在线观看| 在线免费观看羞羞视频一区二区| 亚洲国产精品视频在线观看| 亚洲xxx视频| 色哟哟亚洲精品一区二区| 在线观看中文字幕亚洲| 欧美激情手机在线视频| 欧美噜噜久久久xxx| 日韩在线观看免费| 国产成人精品一区二区在线| 亚洲春色另类小说| 97久久久免费福利网址| 一区二区三区美女xx视频| 国产精品久久久久久久天堂| 久久久噜噜噜久久中文字免| 日韩免费在线观看视频| 欧美激情视频免费观看| 国产精品视频99| 国产精品网站入口| 国产在线高清精品| 欧美日韩成人在线视频| 久久久av免费| 国产精品入口夜色视频大尺度| 久久精品国产69国产精品亚洲| 欧美日韩激情视频8区| 精品国产91乱高清在线观看| 久久免费观看视频| 亚洲欧洲激情在线| 国产综合视频在线观看| 91精品久久久久久久久青青| 欧美性xxxxx极品| www.日韩av.com| 欧美性在线视频| 久久成人在线视频| 精品人伦一区二区三区蜜桃免费| 中文字幕免费精品一区| 亚洲自拍在线观看| 亚洲欧美综合区自拍另类| 亚洲一区二区三区在线视频| 国产欧美精品一区二区三区-老狼| 992tv成人免费视频| 日韩精品久久久久久久玫瑰园| 69av视频在线播放| 欧美福利小视频| 美女精品久久久| 91精品国产九九九久久久亚洲| 亚洲免费视频在线观看| 北条麻妃久久精品| 亚洲一区二区久久久| 美女视频久久黄| 国产精品电影久久久久电影网| 久久夜精品香蕉| 92版电视剧仙鹤神针在线观看| 一级做a爰片久久毛片美女图片| 欧美国产中文字幕| 久久国产精品影视| 91精品久久久久久久久久| 久久影视电视剧免费网站| 夜夜嗨av色一区二区不卡| 青青草原成人在线视频| 超碰97人人做人人爱少妇| 国产精品国产三级国产专播精品人| 亚洲图片欧洲图片av| 性欧美办公室18xxxxhd| 亚洲欧洲激情在线| 亚洲综合在线中文字幕| 日韩黄色在线免费观看| 精品国产老师黑色丝袜高跟鞋| 欧美国产第二页| 亚洲日韩欧美视频| 亚洲一区中文字幕| 日韩精品在线视频观看| 亚洲精品动漫久久久久| 久久久伊人欧美| 欧美激情免费在线| 91wwwcom在线观看| 久久久精品国产网站| 国产精品日本精品| 久久精品夜夜夜夜夜久久| 欧美高清视频一区二区| 亚洲国产成人精品一区二区| 在线看日韩av| 国产精品爱啪在线线免费观看| 亚洲第一网站男人都懂| 亚洲精品成a人在线观看| 2019国产精品自在线拍国产不卡| 91亚洲精品一区| 亚洲综合在线小说| 精品久久久视频| 国产精品观看在线亚洲人成网| 91视频国产高清| 欧美日韩成人免费| 久久精品最新地址| 欧美另类在线观看| 国产aaa精品| 国产专区欧美专区| 成人免费xxxxx在线观看| 久久色在线播放| 亚洲综合中文字幕68页| 日韩不卡中文字幕| 久久免费视频观看| 成人精品福利视频| 久久久久久国产免费| 欧美老女人性视频| 亚洲精品资源美女情侣酒店| 91中文字幕在线观看| 欧美性猛交xxxx久久久| 欧美激情视频给我| 91精品国产自产在线老师啪| 欧美性视频在线| 日韩av在线免费看|