Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
TinySTL
提交
dacad38a
T
TinySTL
项目概览
OpenDocCN
/
TinySTL
通知
4
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TinySTL
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
dacad38a
编写于
1月 15, 2015
作者:
邹
邹晓航
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
重构
上级
590652f0
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
312 addition
and
296 deletion
+312
-296
TinySTL/AVLTree.h
TinySTL/AVLTree.h
+27
-296
TinySTL/Detail/AVLTree.impl.h
TinySTL/Detail/AVLTree.impl.h
+285
-0
未找到文件。
TinySTL/AVLTree.h
浏览文件 @
dacad38a
...
...
@@ -8,7 +8,7 @@
#include <set>
namespace
TinySTL
{
namespace
{
namespace
Detail
{
template
<
class
T
>
class
avl_iter
;
}
...
...
@@ -17,7 +17,7 @@ namespace TinySTL{
class
avl_tree
{
private:
template
<
class
T
>
friend
class
avl_iter
;
friend
class
Detail
::
avl_iter
;
private:
struct
node
{
T
data_
;
...
...
@@ -30,7 +30,7 @@ namespace TinySTL{
typedef
TinySTL
::
allocator
<
node
>
dataAllocator
;
public:
typedef
T
value_type
;
typedef
avl_iter
<
node
>
const_iterator
;
typedef
Detail
::
avl_iter
<
node
>
const_iterator
;
typedef
const
T
&
const_reference
;
typedef
size_t
size_type
;
private:
...
...
@@ -40,7 +40,7 @@ namespace TinySTL{
avl_tree
()
:
root_
(
0
),
size_
(
0
){}
avl_tree
(
const
avl_tree
&
)
=
delete
;
avl_tree
&
operator
=
(
const
avl_tree
&
)
=
delete
;
~
avl_tree
()
{
destroyAndDeallocateAllNodes
(
root_
);
}
~
avl_tree
()
;
void
insert
(
const
T
&
val
);
template
<
class
Iterator
>
...
...
@@ -50,235 +50,37 @@ namespace TinySTL{
size_t
height
()
const
{
return
getHeight
(
root_
);
}
size_t
size
()
const
{
return
size_
;
}
bool
empty
()
const
{
return
root_
==
0
;
}
const_iterator
root
(){
return
const_iterator
(
root_
,
this
);
}
const_iterator
root
()
const
{
return
const_iterator
(
root_
,
this
);
}
const_iterator
cbegin
(){
return
find_min
();
}
const_iterator
cend
(){
return
const_iterator
(
0
,
this
);
}
const_iterator
cbegin
()
const
{
return
find_min
();
}
const_iterator
cend
()
const
{
return
const_iterator
(
0
,
this
);
}
const_iterator
find_min
();
const_iterator
find_max
();
const_iterator
find
(
const
T
&
val
);
const_iterator
find_min
()
const
;
const_iterator
find_max
()
const
;
const_iterator
find
(
const
T
&
val
)
const
;
void
print_preorder
(
const
string
&
delim
=
" "
,
std
::
ostream
&
os
=
std
::
cout
)
const
;
void
print_inorder
(
const
string
&
delim
=
" "
,
std
::
ostream
&
os
=
std
::
cout
)
const
;
void
print_postorder
(
const
string
&
delim
=
" "
,
std
::
ostream
&
os
=
std
::
cout
)
const
;
void
print_levelorder
(
const
string
&
delim
=
" "
,
std
::
ostream
&
os
=
std
::
cout
)
const
;
private:
node
*
singleLeftLeftRotate
(
node
*
k2
){
auto
k1
=
k2
->
left_
;
k2
->
left_
=
k1
->
right_
;
k1
->
right_
=
k2
;
k2
->
height_
=
max
(
getHeight
(
k2
->
left_
),
getHeight
(
k2
->
right_
))
+
1
;
k1
->
height_
=
max
(
getHeight
(
k1
->
left_
),
k2
->
height_
)
+
1
;
return
k1
;
}
node
*
doubleLeftRightRotate
(
node
*
k3
){
k3
->
left_
=
singleRightRightRotate
(
k3
->
left_
);
return
singleLeftLeftRotate
(
k3
);
}
node
*
doubleRightLeftRotate
(
node
*
k3
){
k3
->
right_
=
singleLeftLeftRotate
(
k3
->
right_
);
return
singleRightRightRotate
(
k3
);
}
node
*
singleRightRightRotate
(
node
*
k2
){
auto
k1
=
k2
->
right_
;
k2
->
right_
=
k1
->
left_
;
k1
->
left_
=
k2
;
k2
->
height_
=
max
(
getHeight
(
k2
->
left_
),
getHeight
(
k2
->
right_
))
+
1
;
k1
->
height_
=
max
(
k2
->
height_
,
getHeight
(
k1
->
right_
))
+
1
;
return
k1
;
}
node
*
singleLeftLeftRotate
(
node
*
k2
);
node
*
doubleLeftRightRotate
(
node
*
k3
);
node
*
doubleRightLeftRotate
(
node
*
k3
);
node
*
singleRightRightRotate
(
node
*
k2
);
private:
void
insert_elem
(
const
T
&
val
,
node
*&
p
);
void
erase_elem
(
const
T
&
val
,
node
*&
p
);
void
destroyAndDeallocateAllNodes
(
node
*
p
){
if
(
p
!=
0
){
destroyAndDeallocateAllNodes
(
p
->
left_
);
destroyAndDeallocateAllNodes
(
p
->
right_
);
dataAllocator
::
destroy
(
p
);
dataAllocator
::
deallocate
(
p
);
}
}
void
destroyAndDeallocateAllNodes
(
node
*
p
);
size_t
getHeight
(
const
node
*
p
)
const
{
return
p
==
0
?
0
:
p
->
height_
;
}
const_iterator
find_min_aux
(
const
node
*
ptr
);
const_iterator
find_max_aux
(
const
node
*
ptr
);
const_iterator
find_aux
(
const
T
&
val
,
const
node
*
ptr
);
const_iterator
find_min_aux
(
const
node
*
ptr
)
const
;
const_iterator
find_max_aux
(
const
node
*
ptr
)
const
;
const_iterator
find_aux
(
const
T
&
val
,
const
node
*
ptr
)
const
;
void
print_preorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
;
void
print_inorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
;
void
print_postorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
;
};
// end of avl_tree
template
<
class
T
>
void
avl_tree
<
T
>::
erase_elem
(
const
T
&
val
,
node
*&
p
){
if
(
p
==
0
)
return
;
if
(
p
->
data_
<
val
){
erase_elem
(
val
,
p
->
right_
);
}
else
if
(
p
->
data_
>
val
){
erase_elem
(
val
,
p
->
left_
);
}
else
{
// found
if
(
p
->
left_
!=
0
&&
p
->
right_
!=
0
){
//has two children
size_t
choose
=
size_
%
2
;
//随机选择删除左右,使得删除操作更平衡
auto
pos
=
(
choose
==
0
?
const_cast
<
node
*>
(
find_min_aux
(
p
->
right_
).
ptr_
)
:
const_cast
<
node
*>
(
find_max_aux
(
p
->
left_
).
ptr_
));
p
->
data_
=
pos
->
data_
;
(
choose
==
0
?
erase_elem
(
pos
->
data_
,
p
->
right_
)
:
erase_elem
(
pos
->
data_
,
p
->
left_
));
}
else
{
//has one or no child
auto
temp
=
p
;
if
(
p
->
left_
==
0
)
p
=
p
->
right_
;
else
p
=
p
->
left_
;
dataAllocator
::
deallocate
(
temp
);
--
size_
;
}
}
if
(
p
!=
0
){
//最后更新p的节点高度信息和旋转维持平衡
p
->
height_
=
max
(
getHeight
(
p
->
left_
),
getHeight
(
p
->
right_
))
+
1
;
if
(
getHeight
(
p
->
left_
)
-
getHeight
(
p
->
right_
)
==
2
){
if
(
p
->
left_
->
right_
==
0
)
singleLeftLeftRotate
(
p
);
else
doubleLeftRightRotate
(
p
);
}
else
if
(
getHeight
(
p
->
right_
)
-
getHeight
(
p
->
left_
)
==
2
){
if
(
p
->
right_
->
left_
==
0
)
singleRightRightRotate
(
p
);
else
doubleRightLeftRotate
(
p
);
}
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
erase
(
const
T
&
val
){
return
erase_elem
(
val
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
insert_elem
(
const
T
&
val
,
node
*&
p
){
if
(
p
==
0
){
p
=
dataAllocator
::
allocate
();
//p->data_ = val;
construct
(
&
(
p
->
data_
),
val
);
p
->
left_
=
p
->
right_
=
0
;
p
->
height_
=
1
;
++
size_
;
}
else
if
(
p
->
data_
<
val
){
insert_elem
(
val
,
p
->
right_
);
if
(
getHeight
(
p
->
right_
)
-
getHeight
(
p
->
left_
)
==
2
){
if
(
val
>
p
->
right_
->
data_
)
p
=
singleRightRightRotate
(
p
);
else
p
=
doubleRightLeftRotate
(
p
);
}
}
else
{
insert_elem
(
val
,
p
->
left_
);
if
(
getHeight
(
p
->
left_
)
-
getHeight
(
p
->
right_
)
==
2
){
if
(
val
<
p
->
left_
->
data_
)
p
=
singleLeftLeftRotate
(
p
);
else
p
=
doubleLeftRightRotate
(
p
);
}
}
p
->
height_
=
max
(
getHeight
(
p
->
left_
),
getHeight
(
p
->
right_
))
+
1
;
}
template
<
class
T
>
void
avl_tree
<
T
>::
insert
(
const
T
&
val
){
return
insert_elem
(
val
,
root_
);
}
template
<
class
T
>
template
<
class
Iterator
>
void
avl_tree
<
T
>::
insert
(
Iterator
first
,
Iterator
last
){
for
(;
first
!=
last
;
++
first
)
insert
(
*
first
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_preorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
{
if
(
ptr
!=
0
){
os
<<
ptr
->
data_
<<
delim
;
print_preorder_aux
(
delim
,
os
,
ptr
->
left_
);
print_preorder_aux
(
delim
,
os
,
ptr
->
right_
);
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_preorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
print_preorder_aux
(
delim
,
os
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_inorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
{
if
(
ptr
!=
0
){
print_inorder_aux
(
delim
,
os
,
ptr
->
left_
);
os
<<
ptr
->
data_
<<
delim
;
print_inorder_aux
(
delim
,
os
,
ptr
->
right_
);
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_inorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
print_inorder_aux
(
delim
,
os
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_postorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
{
if
(
ptr
!=
0
){
print_postorder_aux
(
delim
,
os
,
ptr
->
left_
);
print_postorder_aux
(
delim
,
os
,
ptr
->
right_
);
os
<<
ptr
->
data_
<<
delim
;
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_postorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
print_postorder_aux
(
delim
,
os
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_levelorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
auto
temp
=
root_
;
if
(
temp
!=
0
){
std
::
deque
<
node
*>
q
;
q
.
push_back
(
temp
);
while
(
!
q
.
empty
()){
temp
=
q
.
front
();
q
.
pop_front
();
os
<<
temp
->
data_
<<
delim
;
if
(
temp
->
left_
!=
0
)
q
.
push_back
(
temp
->
left_
);
if
(
temp
->
right_
!=
0
)
q
.
push_back
(
temp
->
right_
);
}
}
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_aux
(
const
T
&
val
,
const
node
*
ptr
){
while
(
ptr
!=
0
){
if
(
ptr
->
data_
<
val
)
ptr
=
ptr
->
right_
;
else
if
(
ptr
->
data_
>
val
)
ptr
=
ptr
->
left_
;
else
break
;
}
return
const_iterator
(
ptr
,
this
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find
(
const
T
&
val
){
return
find_aux
(
val
,
root_
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_max_aux
(
const
node
*
ptr
){
while
(
ptr
!=
0
&&
ptr
->
right_
!=
0
)
ptr
=
ptr
->
right_
;
return
const_iterator
(
ptr
,
this
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_max
(){
return
find_max_aux
(
root_
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_min_aux
(
const
node
*
ptr
){
while
(
ptr
!=
0
&&
ptr
->
left_
!=
0
)
ptr
=
ptr
->
left_
;
return
const_iterator
(
ptr
,
this
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_min
(){
return
find_min_aux
(
root_
);
}
namespace
{
namespace
Detail
{
//class of avl tree iterator
template
<
class
T
>
//T = node
class
avl_iter
{
...
...
@@ -289,104 +91,33 @@ namespace TinySTL{
typedef
typename
avl_tree
<
typename
T
::
value_type
>::
value_type
value_type
;
typedef
typename
avl_tree
<
typename
T
::
value_type
>::
const_reference
const_reference
;
typedef
typename
const
T
::
value_type
*
const_pointer
;
typedef
avl_tree
<
typename
T
::
value_type
>
*
cntrPtr
;
typedef
const
avl_tree
<
typename
T
::
value_type
>
*
cntrPtr
;
private:
const
T
*
ptr_
;
cntrPtr
container_
;
stack
<
const
T
*>
parent_
;
//保存从root到ptr_的父节点的路径
std
::
set
<
const
T
*>
visited_
;
std
::
set
<
const
T
*>
visited_
;
//当前节点是否被访问过(此node被访问说明其左子树已被访问了)
public:
avl_iter
(
const
T
*
ptr
,
cntrPtr
container
)
:
ptr_
(
ptr
),
container_
(
container
){
auto
temp
=
container_
->
root_
;
while
(
temp
&&
ptr_
&&
temp
!=
ptr_
&&
temp
->
data_
!=
ptr_
->
data_
){
parent_
.
push
(
temp
);
if
(
temp
->
data_
<
ptr_
->
data_
)
temp
=
temp
->
right_
;
else
if
(
temp
->
data_
>
ptr_
->
data_
)
temp
=
temp
->
left_
;
}
}
avl_iter
(
const
T
*
ptr
,
cntrPtr
container
);
operator
const
T
*
(){
return
ptr_
;
}
const_reference
operator
*
(){
return
ptr_
->
data_
;
}
const_pointer
operator
->
(){
return
&
(
operator
*
());
}
operator
const
T
*
()
const
{
return
ptr_
;
}
const_reference
operator
*
()
const
{
return
ptr_
->
data_
;
}
const_pointer
operator
->
()
const
{
return
&
(
operator
*
());
}
avl_iter
left
()
const
{
return
avl_iter
(
ptr_
->
left_
,
container_
);
}
avl_iter
right
()
const
{
return
avl_iter
(
ptr_
->
right_
,
container_
);
}
avl_iter
&
operator
++
();
avl_iter
operator
++
(
int
);
avl_iter
&
operator
--
();
avl_iter
operator
--
(
int
);
public:
template
<
class
T
>
friend
bool
operator
==
(
const
avl_iter
<
T
>&
it1
,
const
avl_iter
<
T
>&
it2
);
template
<
class
T
>
friend
bool
operator
!=
(
const
avl_iter
<
T
>&
it1
,
const
avl_iter
<
T
>&
it2
);
};
//end of avl_iter
template
<
class
T
>
avl_iter
<
T
>&
avl_iter
<
T
>::
operator
++
(){
visited_
.
insert
(
ptr_
);
//设为已访问
if
(
ptr_
->
right_
!=
0
){
parent_
.
push
(
ptr_
);
ptr_
=
ptr_
->
right_
;
while
(
ptr_
!=
0
&&
ptr_
->
left_
!=
0
){
parent_
.
push
(
ptr_
);
ptr_
=
ptr_
->
left_
;
}
}
else
{
if
(
!
parent_
.
empty
()
&&
visited_
.
count
(
parent_
.
top
())
==
0
){
//父节点未访问
ptr_
=
parent_
.
top
();
parent_
.
pop
();
}
else
{
ptr_
=
0
;
}
}
return
*
this
;
}
template
<
class
T
>
avl_iter
<
T
>
avl_iter
<
T
>::
operator
++
(
int
){
auto
res
=
*
this
;
++*
this
;
return
res
;
}
template
<
class
T
>
avl_iter
<
T
>&
avl_iter
<
T
>::
operator
--
(){
visited_
.
erase
(
ptr_
);
//设为未访问
if
(
ptr_
->
left_
!=
0
){
parent_
.
push
(
ptr_
);
ptr_
=
ptr_
->
left_
;
while
(
ptr_
&&
ptr_
->
right_
){
parent_
.
push
(
ptr_
);
ptr_
=
ptr_
->
right_
;
}
}
else
{
if
(
!
parent_
.
empty
()
&&
visited_
.
count
(
parent_
.
top
())
==
1
){
//父节点已经访问了
ptr_
=
parent_
.
top
();
parent_
.
pop
();
}
}
return
*
this
;
}
template
<
class
T
>
avl_iter
<
T
>
avl_iter
<
T
>::
operator
--
(
int
){
auto
res
=
*
this
;
--*
this
;
return
res
;
}
template
<
class
T
>
bool
operator
==
(
const
avl_iter
<
T
>&
it1
,
const
avl_iter
<
T
>&
it2
){
return
it1
.
ptr_
==
it2
.
ptr_
;
}
template
<
class
T
>
bool
operator
!=
(
const
avl_iter
<
T
>&
it1
,
const
avl_iter
<
T
>&
it2
){
return
!
(
it1
==
it2
);
}
}
}
#include "Detail\AVLTree.impl.h"
#endif
\ No newline at end of file
TinySTL/Detail/AVLTree.impl.h
0 → 100644
浏览文件 @
dacad38a
#ifndef _AVL_TREE_IMPL_H_
#define _AVL_TREE_IMPL_H_
namespace
TinySTL
{
namespace
Detail
{
template
<
class
T
>
avl_iter
<
T
>::
avl_iter
(
const
T
*
ptr
,
cntrPtr
container
)
:
ptr_
(
ptr
),
container_
(
container
){
if
(
!
ptr_
)
return
;
auto
temp
=
container_
->
root_
;
while
(
temp
&&
temp
!=
ptr_
&&
temp
->
data_
!=
ptr_
->
data_
){
parent_
.
push
(
temp
);
if
(
temp
->
data_
<
ptr_
->
data_
){
//temp向右走说明temo指向的父节点不需要再次访问了
visited_
.
insert
(
temp
);
//add 2015.01.14
temp
=
temp
->
right_
;
}
else
if
(
temp
->
data_
>
ptr_
->
data_
){
temp
=
temp
->
left_
;
}
}
}
template
<
class
T
>
avl_iter
<
T
>&
avl_iter
<
T
>::
operator
++
(){
visited_
.
insert
(
ptr_
);
//此node被访问
if
(
ptr_
->
right_
){
//此node还有右子树
//rvisited_.insert(ptr_);
parent_
.
push
(
ptr_
);
ptr_
=
ptr_
->
right_
;
while
(
ptr_
&&
ptr_
->
left_
){
parent_
.
push
(
ptr_
);
ptr_
=
ptr_
->
left_
;
}
}
else
{
//node无右子树则只能向父节点路径移动
ptr_
=
0
;
//add 2015.01.14
while
(
!
parent_
.
empty
()){
ptr_
=
parent_
.
top
();
parent_
.
pop
();
if
(
visited_
.
count
(
ptr_
)
==
0
){
//父节点尚未访问,此时ptr_指向此节点
visited_
.
insert
(
ptr_
);
break
;
}
ptr_
=
0
;
//设为哨兵
}
//end of while
}
//end of if
return
*
this
;
}
template
<
class
T
>
avl_iter
<
T
>
avl_iter
<
T
>::
operator
++
(
int
){
auto
res
=
*
this
;
++*
this
;
return
res
;
}
template
<
class
T
>
bool
operator
==
(
const
avl_iter
<
T
>&
it1
,
const
avl_iter
<
T
>&
it2
){
return
it1
.
ptr_
==
it2
.
ptr_
;
}
template
<
class
T
>
bool
operator
!=
(
const
avl_iter
<
T
>&
it1
,
const
avl_iter
<
T
>&
it2
){
return
!
(
it1
==
it2
);
}
}
//end of Detail namespace
template
<
class
T
>
typename
avl_tree
<
T
>::
node
*
avl_tree
<
T
>::
singleLeftLeftRotate
(
node
*
k2
){
auto
k1
=
k2
->
left_
;
k2
->
left_
=
k1
->
right_
;
k1
->
right_
=
k2
;
k2
->
height_
=
max
(
getHeight
(
k2
->
left_
),
getHeight
(
k2
->
right_
))
+
1
;
k1
->
height_
=
max
(
getHeight
(
k1
->
left_
),
k2
->
height_
)
+
1
;
return
k1
;
}
template
<
class
T
>
typename
avl_tree
<
T
>::
node
*
avl_tree
<
T
>::
doubleLeftRightRotate
(
node
*
k3
){
k3
->
left_
=
singleRightRightRotate
(
k3
->
left_
);
return
singleLeftLeftRotate
(
k3
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
node
*
avl_tree
<
T
>::
doubleRightLeftRotate
(
node
*
k3
){
k3
->
right_
=
singleLeftLeftRotate
(
k3
->
right_
);
return
singleRightRightRotate
(
k3
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
node
*
avl_tree
<
T
>::
singleRightRightRotate
(
node
*
k2
){
auto
k1
=
k2
->
right_
;
k2
->
right_
=
k1
->
left_
;
k1
->
left_
=
k2
;
k2
->
height_
=
max
(
getHeight
(
k2
->
left_
),
getHeight
(
k2
->
right_
))
+
1
;
k1
->
height_
=
max
(
k2
->
height_
,
getHeight
(
k1
->
right_
))
+
1
;
return
k1
;
}
template
<
class
T
>
void
avl_tree
<
T
>::
destroyAndDeallocateAllNodes
(
node
*
p
){
if
(
p
!=
0
){
destroyAndDeallocateAllNodes
(
p
->
left_
);
destroyAndDeallocateAllNodes
(
p
->
right_
);
dataAllocator
::
destroy
(
p
);
dataAllocator
::
deallocate
(
p
);
}
}
template
<
class
T
>
avl_tree
<
T
>::~
avl_tree
(){
destroyAndDeallocateAllNodes
(
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
erase_elem
(
const
T
&
val
,
node
*&
p
){
if
(
p
==
0
)
return
;
if
(
p
->
data_
<
val
){
erase_elem
(
val
,
p
->
right_
);
}
else
if
(
p
->
data_
>
val
){
erase_elem
(
val
,
p
->
left_
);
}
else
{
// found
if
(
p
->
left_
!=
0
&&
p
->
right_
!=
0
){
//has two children
size_t
choose
=
size_
%
2
;
//随机选择删除左右,使得删除操作更平衡
auto
pos
=
(
choose
==
0
?
const_cast
<
node
*>
(
find_min_aux
(
p
->
right_
).
ptr_
)
:
const_cast
<
node
*>
(
find_max_aux
(
p
->
left_
).
ptr_
));
p
->
data_
=
pos
->
data_
;
(
choose
==
0
?
erase_elem
(
pos
->
data_
,
p
->
right_
)
:
erase_elem
(
pos
->
data_
,
p
->
left_
));
}
else
{
//has one or no child
auto
temp
=
p
;
if
(
p
->
left_
==
0
)
p
=
p
->
right_
;
else
p
=
p
->
left_
;
dataAllocator
::
deallocate
(
temp
);
--
size_
;
}
}
if
(
p
!=
0
){
//最后更新p的节点高度信息和旋转维持平衡
p
->
height_
=
max
(
getHeight
(
p
->
left_
),
getHeight
(
p
->
right_
))
+
1
;
if
(
getHeight
(
p
->
left_
)
-
getHeight
(
p
->
right_
)
==
2
){
if
(
p
->
left_
->
right_
==
0
)
singleLeftLeftRotate
(
p
);
else
doubleLeftRightRotate
(
p
);
}
else
if
(
getHeight
(
p
->
right_
)
-
getHeight
(
p
->
left_
)
==
2
){
if
(
p
->
right_
->
left_
==
0
)
singleRightRightRotate
(
p
);
else
doubleRightLeftRotate
(
p
);
}
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
erase
(
const
T
&
val
){
return
erase_elem
(
val
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
insert_elem
(
const
T
&
val
,
node
*&
p
){
if
(
p
==
0
){
p
=
dataAllocator
::
allocate
();
//p->data_ = val;
construct
(
&
(
p
->
data_
),
val
);
p
->
left_
=
p
->
right_
=
0
;
p
->
height_
=
1
;
++
size_
;
}
else
if
(
p
->
data_
<
val
){
insert_elem
(
val
,
p
->
right_
);
if
(
getHeight
(
p
->
right_
)
-
getHeight
(
p
->
left_
)
==
2
){
if
(
val
>
p
->
right_
->
data_
)
p
=
singleRightRightRotate
(
p
);
else
p
=
doubleRightLeftRotate
(
p
);
}
}
else
if
(
p
->
data_
>
val
){
insert_elem
(
val
,
p
->
left_
);
if
(
getHeight
(
p
->
left_
)
-
getHeight
(
p
->
right_
)
==
2
){
if
(
val
<
p
->
left_
->
data_
)
p
=
singleLeftLeftRotate
(
p
);
else
p
=
doubleLeftRightRotate
(
p
);
}
}
p
->
height_
=
max
(
getHeight
(
p
->
left_
),
getHeight
(
p
->
right_
))
+
1
;
}
template
<
class
T
>
void
avl_tree
<
T
>::
insert
(
const
T
&
val
){
return
insert_elem
(
val
,
root_
);
}
template
<
class
T
>
template
<
class
Iterator
>
void
avl_tree
<
T
>::
insert
(
Iterator
first
,
Iterator
last
){
for
(;
first
!=
last
;
++
first
)
insert
(
*
first
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_preorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
{
if
(
ptr
!=
0
){
os
<<
ptr
->
data_
<<
delim
;
print_preorder_aux
(
delim
,
os
,
ptr
->
left_
);
print_preorder_aux
(
delim
,
os
,
ptr
->
right_
);
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_preorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
print_preorder_aux
(
delim
,
os
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_inorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
{
if
(
ptr
!=
0
){
print_inorder_aux
(
delim
,
os
,
ptr
->
left_
);
os
<<
ptr
->
data_
<<
delim
;
print_inorder_aux
(
delim
,
os
,
ptr
->
right_
);
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_inorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
print_inorder_aux
(
delim
,
os
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_postorder_aux
(
const
string
&
delim
,
std
::
ostream
&
os
,
const
node
*
ptr
)
const
{
if
(
ptr
!=
0
){
print_postorder_aux
(
delim
,
os
,
ptr
->
left_
);
print_postorder_aux
(
delim
,
os
,
ptr
->
right_
);
os
<<
ptr
->
data_
<<
delim
;
}
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_postorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
print_postorder_aux
(
delim
,
os
,
root_
);
}
template
<
class
T
>
void
avl_tree
<
T
>::
print_levelorder
(
const
string
&
delim
,
std
::
ostream
&
os
)
const
{
auto
temp
=
root_
;
if
(
temp
!=
0
){
std
::
deque
<
node
*>
q
;
q
.
push_back
(
temp
);
while
(
!
q
.
empty
()){
temp
=
q
.
front
();
q
.
pop_front
();
os
<<
temp
->
data_
<<
delim
;
if
(
temp
->
left_
!=
0
)
q
.
push_back
(
temp
->
left_
);
if
(
temp
->
right_
!=
0
)
q
.
push_back
(
temp
->
right_
);
}
}
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_aux
(
const
T
&
val
,
const
node
*
ptr
)
const
{
while
(
ptr
!=
0
){
if
(
ptr
->
data_
<
val
)
ptr
=
ptr
->
right_
;
else
if
(
ptr
->
data_
>
val
)
ptr
=
ptr
->
left_
;
else
break
;
}
return
const_iterator
(
ptr
,
this
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find
(
const
T
&
val
)
const
{
return
find_aux
(
val
,
root_
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_max_aux
(
const
node
*
ptr
)
const
{
while
(
ptr
!=
0
&&
ptr
->
right_
!=
0
)
ptr
=
ptr
->
right_
;
return
const_iterator
(
ptr
,
this
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_max
()
const
{
return
find_max_aux
(
root_
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_min_aux
(
const
node
*
ptr
)
const
{
while
(
ptr
!=
0
&&
ptr
->
left_
!=
0
)
ptr
=
ptr
->
left_
;
return
const_iterator
(
ptr
,
this
);
}
template
<
class
T
>
typename
avl_tree
<
T
>::
const_iterator
avl_tree
<
T
>::
find_min
()
const
{
return
find_min_aux
(
root_
);
}
}
#endif
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录