浙大数据结构:04-树5 Root of AVL Tree

这道题核心平衡树的代码在MOOC上有,需要完善修改即可。
机翻

1、条件准备

定义结构体,高度,值,左结点,右结点
cpp 复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct AVLNode *position;
typedef position AVLTree;
typedef int ElementType;
struct AVLNode
{
  ElementType data;
  AVLTree Left;
  AVLTree Right;
  int height;
};
主函数读入结点,调用insert函数插入,最后输出根节点值
cpp 复制代码
int main()
{
  int n;
  cin >> n;
  AVLTree T = NULL;
  for (int i = 0; i < n; i++)
  {
    int a;
    cin >> a;
    T = insert(T, a);
  }
  cout << T->data;

  return 0;
}

2、平衡树四种旋转

具体逻辑在MOOC的ppt上有讲述,如果对代码不太理解我建议举例子推一遍比较好
cpp 复制代码
AVLTree singleleftrotation(AVLTree A)
{
 //左左
  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 singlerightrotation(AVLTree A)
{
//右右
  AVLTree B = A->Right;
  A->Right = B->Left;
  B->Left = A;
  A->height = max(getheight(A->Left), getheight(A->Right)) + 1;
  B->height = max(getheight(B->Right), A->height) + 1;

  return B;
}

AVLTree doubleleftrotation(AVLTree A)
{
//左右
  A->Left = singlerightrotation(A->Left);
  return singleleftrotation(A);
}

AVLTree doublerightrotation(AVLTree A)
{
//右左
  A->Right = singleleftrotation(A->Right);
  return singlerightrotation(A);
}

3、getheight函数

获取树高度,递归实现
cpp 复制代码
int getheight(AVLTree A)
{
  if (!A)
    return 0;
  return max(getheight(A->Left), getheight(A->Right)) + 1;
}

4、insert函数

跟MOOC上代码逻辑基本一样。
cpp 复制代码
AVLTree insert(AVLTree T, ElementType x)
{

  if (!T)
  {
    AVLTree T = (AVLTree)malloc(sizeof(struct AVLNode));
    T->data = x;
    T->Right = T->Left = NULL;
    return T;
  }
  else if (x < T->data)
  {
    T->Left = insert(T->Left, x);
    if (getheight(T->Left) - getheight(T->Right) == 2)
    {
      if (x < T->Left->data)
        T = singleleftrotation(T);
      else
        T = doubleleftrotation(T);
    }
  }
  else if (x > T->data)
  {
    T->Right = insert(T->Right, x);
    if (getheight(T->Right) - getheight(T->Left) == 2)
    {
      if (x > T->Right->data)
        T = singlerightrotation(T);
      else
        T = doublerightrotation(T);
    }
  }
  T->height = max(getheight(T->Left), getheight(T->Right)) + 1;

  return T;
}

5、总结

这个题最难的在于平衡树代码和插入代码的实现,不过MOOC上也写出了不少,所以难度不算大。
完整代码如下:
cpp 复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct AVLNode *position;
typedef position AVLTree;
typedef int ElementType;
struct AVLNode
{
  ElementType data;
  AVLTree Left;
  AVLTree Right;
  int height;
};

int getheight(AVLTree A)
{
  if (!A)
    return 0;
  return max(getheight(A->Left), getheight(A->Right)) + 1;
}

AVLTree singleleftrotation(AVLTree A)
{
  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 singlerightrotation(AVLTree A)
{
  AVLTree B = A->Right;
  A->Right = B->Left;
  B->Left = A;
  A->height = max(getheight(A->Left), getheight(A->Right)) + 1;
  B->height = max(getheight(B->Right), A->height) + 1;

  return B;
}

AVLTree doubleleftrotation(AVLTree A)
{
  A->Left = singlerightrotation(A->Left);
  return singleleftrotation(A);
}

AVLTree doublerightrotation(AVLTree A)
{
  A->Right = singleleftrotation(A->Right);
  return singlerightrotation(A);
}

AVLTree insert(AVLTree T, ElementType x)
{

  if (!T)
  {
    AVLTree T = (AVLTree)malloc(sizeof(struct AVLNode));
    T->data = x;
    T->Right = T->Left = NULL;
    return T;
  }
  else if (x < T->data)
  {
    T->Left = insert(T->Left, x);
    if (getheight(T->Left) - getheight(T->Right) == 2)
    {
      if (x < T->Left->data)
        T = singleleftrotation(T);
      else
        T = doubleleftrotation(T);
    }
  }
  else if (x > T->data)
  {
    T->Right = insert(T->Right, x);
    if (getheight(T->Right) - getheight(T->Left) == 2)
    {
      if (x > T->Right->data)
        T = singlerightrotation(T);
      else
        T = doublerightrotation(T);
    }
  }
  T->height = max(getheight(T->Left), getheight(T->Right)) + 1;

  return T;
}

int main()
{
  int n;
  cin >> n;
  AVLTree T = NULL;
  for (int i = 0; i < n; i++)
  {
    int a;
    cin >> a;
    T = insert(T, a);
  }
  cout << T->data;

  return 0;
}
相关推荐
m0_639906947 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
Sakura_j_h_8 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
ZhengEnCi9 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
程序喵大人9 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
秋天的怀念_David9 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Pniubi9 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_61810 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang10 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
jimy111 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
2601_9707038311 小时前
工业除湿机租赁:把一份租金合同拆开看
大数据·数据结构·算法·数据库架构·推荐算法