Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xingyue MA
xepTemplateLibrary
Commits
22a66b31
Commit
22a66b31
authored
May 20, 2021
by
CDK6182CHR
Browse files
2021.5.20 Graph, UFSet
parent
cbea400b
Changes
3
Hide whitespace changes
Inline
Side-by-side
crossgraph.cpp
0 → 100644
View file @
22a66b31
#include <iostream>
#include <utility>
/// <summary>
/// 教材 p.362
/// 具有固定结点数的有向图的邻接多重表实现 或十字链表
/// 仍然采用int在内部表示结点
/// </summary>
/// <typeparam name="V"></typeparam>
/// <typeparam name="E"></typeparam>
template
<
typename
V
,
typename
E
>
class
CrossGraph
{
public:
//表示从v1到v2的有向边
struct
Edge
{
E
edata
;
int
v1
,
v2
;
Edge
*
path1
;
//出边表
Edge
*
path2
;
//入边表
Edge
()
:
edata
(),
v1
(),
v2
(),
path1
(
nullptr
),
path2
(
nullptr
){}
Edge
(
int
v1_
,
int
v2_
,
const
E
&
data
)
:
edata
(
data
),
v1
(
v1_
),
v2
(
v2_
),
path1
(
nullptr
),
path2
(
nullptr
){}
};
struct
Vertex
{
V
vdata
;
Edge
*
ined
;
//入边表
Edge
*
outed
;
//出边表
Vertex
()
:
vdata
(),
ined
(
nullptr
),
outed
(
nullptr
){}
};
CrossGraph
(
int
size_
);
~
CrossGraph
()
noexcept
;
Edge
*
add_edge
(
int
from
,
int
to
,
const
E
&
data
);
void
add_biedge
(
int
x
,
int
y
,
const
E
&
data
);
void
remove_edge
(
int
from
,
int
to
);
//需要时实现
inline
Edge
*
first_out_edge
(
int
v
)
{
return
vertices
[
v
].
outed
;
}
inline
Edge
*
next_out_edge
(
Edge
*
e
)
{
return
e
->
path1
;
}
Edge
*
first_in_edge
(
int
v
)
{
return
vertices
[
v
].
ined
;
}
Edge
*
next_in_edge
(
Edge
*
e
)
{
return
e
->
path2
;
}
inline
int
get_size
()
const
{
return
size
;
}
CrossGraph
(
const
CrossGraph
&
)
=
delete
;
CrossGraph
(
CrossGraph
&&
)
=
delete
;
CrossGraph
&
operator
=
(
const
CrossGraph
&
)
=
delete
;
CrossGraph
&
operator
=
(
CrossGraph
&&
)
=
delete
;
protected:
int
size
;
//顶点数
Vertex
*
vertices
;
};
template
<
typename
V
,
typename
E
>
CrossGraph
<
V
,
E
>::
CrossGraph
(
int
size_
)
:
size
(
size_
)
{
vertices
=
new
Vertex
[
size
];
}
template
<
typename
V
,
typename
E
>
CrossGraph
<
V
,
E
>::~
CrossGraph
()
noexcept
{
//先按照出边顺序清除表
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
auto
e
=
vertices
[
i
].
outed
;
if
(
e
)
{
auto
e1
=
e
->
path1
;
while
(
e1
)
{
delete
e
;
e
=
e1
;
e1
=
e1
->
path1
;
}
}
}
delete
[]
vertices
;
vertices
=
nullptr
;
}
//注意 插入到各个边的链表的第一位
template
<
typename
V
,
typename
E
>
typename
CrossGraph
<
V
,
E
>::
Edge
*
CrossGraph
<
V
,
E
>::
add_edge
(
int
from
,
int
to
,
const
E
&
data
)
{
auto
e
=
new
Edge
(
from
,
to
,
data
);
e
->
path1
=
vertices
[
from
].
outed
;
vertices
[
from
].
outed
=
e
;
e
->
path2
=
vertices
[
to
].
ined
;
vertices
[
to
].
ined
=
e
;
return
e
;
}
template
<
typename
V
,
typename
E
>
void
CrossGraph
<
V
,
E
>::
add_biedge
(
int
x
,
int
y
,
const
E
&
data
)
{
add_edge
(
x
,
y
,
data
);
add_edge
(
y
,
x
,
data
);
}
digraph_link.cpp
0 → 100644
View file @
22a66b31
#include <iostream>
#include <cstdio>
#include <utility>
/// <summary>
/// 有向图的邻接表表示。暂时只考虑插入的情况。
/// 只维护出边而不维护入边。
/// </summary>
/// <typeparam name="V"></typeparam>
/// <typeparam name="E"></typeparam>
template
<
typename
V
,
typename
E
>
class
Graph
{
public:
struct
Edge
;
struct
Vertex
{
V
vdata
;
Edge
*
adj
;
Vertex
()
:
vdata
(),
adj
(
nullptr
){}
};
struct
Edge
{
E
edata
;
int
to
;
Edge
*
link
;
Edge
(
int
to_
)
:
edata
(),
to
(
to_
),
link
(
nullptr
){}
Edge
(
int
to_
,
const
E
&
data
)
:
edata
(
data
),
to
(
to_
),
link
(
nullptr
){}
};
Graph
(
int
size_
);
~
Graph
();
Edge
*
add_edge
(
int
from
,
int
to
,
const
E
&
data
);
//添加双向边
void
add_biedge
(
int
a
,
int
b
,
const
E
&
data
);
Edge
*
first_edge
(
int
v
);
inline
int
get_size
()
const
{
return
size
;
}
Graph
(
const
Graph
&
)
=
delete
;
Graph
(
Graph
&&
)
=
delete
;
Graph
&
operator
=
(
const
Graph
&
)
=
delete
;
Graph
&
operator
=
(
Graph
&&
)
=
delete
;
protected:
int
size
;
Vertex
*
vertices
;
};
template
<
typename
V
,
typename
E
>
Graph
<
V
,
E
>::
Graph
(
int
size_
)
:
size
(
size_
)
{
vertices
=
new
Vertex
[
size
];
}
template
<
typename
V
,
typename
E
>
Graph
<
V
,
E
>::~
Graph
()
{
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
Edge
*
t
=
vertices
[
i
].
adj
;
if
(
t
)
{
Edge
*
t1
=
t
->
link
;
while
(
t1
)
{
delete
t
;
t
=
t1
;
t1
=
t1
->
link
;
}
}
vertices
[
i
].
adj
=
nullptr
;
}
delete
[]
vertices
;
vertices
=
nullptr
;
}
// 注意 这是插入到第一个
template
<
typename
V
,
typename
E
>
typename
Graph
<
V
,
E
>::
Edge
*
Graph
<
V
,
E
>::
add_edge
(
int
from
,
int
to
,
const
E
&
data
)
{
Edge
*
e
=
new
Edge
(
to
,
data
);
e
->
link
=
vertices
[
from
].
adj
;
vertices
[
from
].
adj
=
e
;
return
e
;
}
template
<
typename
V
,
typename
E
>
void
Graph
<
V
,
E
>::
add_biedge
(
int
a
,
int
b
,
const
E
&
data
)
{
add_edge
(
a
,
b
,
data
);
add_edge
(
b
,
a
,
data
);
}
template
<
typename
V
,
typename
E
>
typename
Graph
<
V
,
E
>::
Edge
*
Graph
<
V
,
E
>::
first_edge
(
int
v
)
{
return
vertices
[
v
].
adj
;
}
\ No newline at end of file
ufset.cpp
0 → 100644
View file @
22a66b31
#include <iostream>
#include <utility>
/// <summary>
/// 具有固定长度的UFSet 数组实现
/// 暂时不考虑保存数据的问题 下标就是数据
/// </summary>
/// <typeparam name="T"></typeparam>
class
UFSet
{
int
*
data
;
int
size
;
public:
UFSet
(
int
size_
);
~
UFSet
();
UFSet
(
const
UFSet
&
)
=
delete
;
UFSet
(
UFSet
&&
s
)
noexcept
;
UFSet
&
operator
=
(
const
UFSet
&
)
=
delete
;
UFSet
&
operator
=
(
UFSet
&&
s
)
noexcept
;
int
find
(
int
x
)
const
;
int
find
(
int
x
);
//带路径折叠
int
merge
(
int
x
,
int
y
);
};
UFSet
::
UFSet
(
int
size_
)
:
size
(
size_
)
{
data
=
new
int
[
size
];
std
::
fill
(
data
,
data
+
size
,
-
1
);
}
UFSet
::~
UFSet
()
{
if
(
data
)
delete
[]
data
;
data
=
nullptr
;
}
UFSet
::
UFSet
(
UFSet
&&
s
)
noexcept
:
data
(
s
.
data
),
size
(
s
.
size
)
{
s
.
size
=
0
;
s
.
data
=
nullptr
;
}
UFSet
&
UFSet
::
operator
=
(
UFSet
&&
s
)
noexcept
{
size
=
s
.
size
;
data
=
s
.
data
;
s
.
size
=
0
;
s
.
data
=
nullptr
;
return
*
this
;
}
int
UFSet
::
find
(
int
x
)
const
{
while
(
data
[
x
]
>=
0
)
x
=
data
[
x
];
return
x
;
}
//把路径上所有的都折叠上去
int
UFSet
::
find
(
int
x
)
{
int
root
=
static_cast
<
const
UFSet
*>
(
this
)
->
find
(
x
);
while
(
data
[
x
]
>=
0
)
{
x
=
data
[
x
];
data
[
x
]
=
root
;
}
return
root
;
}
//不负责折叠路径
//只把y合并到x
//返回新的根节点
int
UFSet
::
merge
(
int
x
,
int
y
)
{
int
rx
=
find
(
x
);
int
ry
=
find
(
y
);
data
[
rx
]
+=
data
[
ry
];
data
[
ry
]
=
rx
;
return
rx
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment