1.将一个BST转换成一个有序双向链表
1.1 考虑
- 1.我们需要改变原本BST的结构,因此我们使用 p_left 作为双向链表的指向前的指针,使用 p_right 作为双向链表的指向后的指针;
- 2.将一个BST转换为一个有序的双向链表其实就是将BST的中序遍历中的printf处的代码进行修改,改为给双向链表添加节点;
- 使用递归的形式进行转换
void BSTToList(BinaryTree* p_tree, BinaryTree** pp_head, BinaryTree** pp_tail)
{
if(p_tree == NULL)return;
BSTToList(P_tree->p_left);
if(*pp_head == NULL)
{
*pp_head = p_tree;
}
else
{
*pp_tail->p_right = p_tree;
p_tree->p_left = *pp_tail;
}
*pp_tail = p_tree;
BSTToList(P_tree->p_right);
}
- 不使用递归的形式完成
void BSTToList(BinaryTree* p_tree, BinaryTree** pp_head, BinaryTree** pp_tail)
{
if(p_tree == NULL)return;
// 申请辅助栈
Stack* p_stack = NULL;
s_Init(&p_stack);
while(1)
{
while(p_tree)
{
s_Push(p_stack, p_tree);
p_tree = p_tree->p_left;
}
p_tree = s_Pop(s_stack);
if(p_tree == NULL)break;
// ==========向双向链表中添加节点=========
if(*pp_head == NULL)
{
*pp_head = p_tree;
}
else
{
*pp_tail->p_right = p_tree;
p_tree->p_left = *pp_tail;
}
*pp_tail = p_tree;
// ==========向双向链表中添加节点=========
p_tree = p_tree->p-right;
}
}
2.旋转一颗AVL
2.1 首先考虑一颗类似于下面的AVL
=添加图片==
-
当新加的节点导致AVL树不平衡,那么就需要旋转来将其变平衡;
-
在左子树的左子树上添加节点导致的不平衡需要右旋;
-
在右子树的右子树上添加节点导致的不平衡需要左旋;
-
在左子树的右子树上添加节点导致的不平衡需要左右旋;
-
在右子树的右子树上添加节点导致的不平衡需要右左旋;
-
1.右旋
void RightRotate(BinaryTree** pp_tree)
{
if(*pp_tree == NULL)return;
BinaryTree* p_node = *pp_tree;
BinaryTree* p_flag = p_node->p_left;
// 三个孩子的关系
p_node->p_left = p_flag->p_right;
p_flag->p_right = p_node;
// 支点(顶点A)的父亲存在(也就是说A不是根节点)
if(p_node->p_father != NULL)
{
// 顶点是它父亲节点的左节点
if(p_node == p_node->p_father->p_left)
{
p_node->p_father->p_left = p_flag;
}
// 顶点是它父亲节点的右节点
else
{
p_node->p_father->p_right = p_flag;
}
}
// 顶点A就是根节点
else
{
*p_tree = p_flag;
}
// 三个父亲的关系
if(p_node->p_left != NULL)
{
p_node->p_left->p_father = p_node;
}
p_flag->p_father = p_node->p_father;
p_node->p_father = p_flag;
}
- 2.左旋
void LeftRotate(BinaryTree** pp_tree)
{
if(*pp_tree == NULL)return;
BinaryTree* p_node = *pp_tree;
BinaryTree* p_flag = p_node->p_right;
// 三个孩子的关系
p_node->p_right = p_flag->p_left;
p_flag->p_left = p_node;
// 支点(顶点A)的父亲存在(也就是说A不是根节点)
if(p_node->p_father != NULL)
{
// 顶点是它父亲节点的左节点
if(p_node == p_node->p_father->p_left)
{
p_node->p_father->p_left = p_flag;
}
// 顶点是它父亲节点的右节点
else
{
p_node->p_father->p_right = p_flag;
}
}
// 顶点A就是根节点
else
{
*p_tree = p_flag;
}
// 三个父亲的关系
if(p_node->p_right != NULL)
{
p_node->p_right->p_father = p_node;
}
p_flag->p_father = p_node->p_father;
p_node->p_father = p_flag;
}