1.3.C语言基础进阶——AVL树的原理及实现
今天的内容比昨天跟的要好,但是代码实践部分速度对于我来说太快了,这个部分没有跟上,课下补的
二叉排序树
数据结构 = 结构定义 + 结构操作,结构操作维护结构定义
又叫做二叉搜索树
性质: 左子树 < 根节点,右子树 > 根节点
基本操作
- 插入:每次插入会插入到叶子节点
- 删除
- 删除叶子节点:最简单,直接删除即可
- 删除出度为1的节点:删除节点后,将其父节点与其子结点相连
- 删除出度为2的节点
- 首先找到该节点的前驱节点,即其左子树中最右节点
- 将前驱节点替换到需要删除的节点位置,并删除原前驱节点
- 使用后继节点,对应修改操作,可以达到相同目的
代码实现
以下给出代码实现,运行后每次可以输入两个数字,其中第一个数字为1表示插入,为2表示删除,第二个数字为该节点值
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define L(n) (n->lchild)
#define R(n) (n->rchild)
#define K(n) (n ? n->key : 0)
typedef struct Node{
int key;
struct Node *lchild, *rchild;
}Node;
//新建节点,值为key
Node *getNewNode(int key){
Node *p = (Node *)malloc(sizeof(Node));
p->key = key;
p->lchild = p->rchild = NULL;
return p;
}
//插入新的节点
Node *insert(Node *root, int key){
if(root == NULL) return getNewNode(key);
if(root->key == key) return root;
if(key < root->key) root->lchild = insert(root->lchild, key);
else root->rchild = insert(root->rchild, key);
return root;
}
//在度为2时候,需要寻找先驱节点以便进行删除操作
//这个函数返回所给节点的先驱节点
//先驱节点即左子树最右边节点
Node *predecessor(Node *root){
Node *temp = root->lchild;
while(temp->rchild) temp = temp->rchild;
return temp;
}
//删除所给节点
Node *erase(Node *root, int key){
if(root == NULL) return NULL;
if(key < root-> key){
root->lchild = erase(root->lchild, key);
} else if(key > root-> key){
root->rchild = erase(root->rchild, key);
} else{
if(root->lchild == NULL || root->rchild == NULL){
Node *temp = root->lchild ? root->lchild : root->rchild;
free