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
038403d0
Commit
038403d0
authored
Jun 07, 2021
by
xep
Browse files
2021.6.7 Undirected-graph
parent
273d706b
Changes
1
Hide whitespace changes
Inline
Side-by-side
unigraph.cpp
0 → 100644
View file @
038403d0
#include <iostream>
#include <utility>
/// <summary>
/// 教材 p.362
/// 具有固定结点数的无向图的邻接多重表实现 或十字链表
/// 仍然采用int在内部表示结点
/// </summary>
template
<
typename
V
,
typename
E
>
class
UniGraph
{
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
*
outed
;
//出边表
Vertex
()
:
vdata
(),
outed
(
nullptr
)
{}
};
UniGraph
(
int
size_
);
~
UniGraph
()
noexcept
;
Edge
*
add_edge
(
int
from
,
int
to
,
const
E
&
data
);
void
remove_edge
(
int
from
,
int
to
);
//需要时实现
inline
Edge
*
first_edge
(
int
v
)
{
return
vertices
[
v
].
outed
;
}
Edge
*
next_edge
(
int
v
,
Edge
*
e
);
inline
int
get_edge_neighbour
(
int
u
,
const
Edge
*
e
)
const
{
return
u
==
e
->
v1
?
e
->
v2
:
e
->
v1
;
}
inline
int
get_size
()
const
{
return
size
;
}
Edge
*
get_edge
(
int
u
,
int
v
);
UniGraph
(
const
UniGraph
&
)
=
delete
;
UniGraph
(
UniGraph
&&
)
=
delete
;
UniGraph
&
operator
=
(
const
UniGraph
&
)
=
delete
;
UniGraph
&
operator
=
(
UniGraph
&&
)
=
delete
;
protected:
int
size
;
//顶点数
Vertex
*
vertices
;
//path1或者path2指针域
Edge
*&
next_edge_ref
(
int
v
,
Edge
*
e
);
//来向的指针
Edge
*
previous_edge
(
int
v
,
Edge
*
e
);
};
template
<
typename
V
,
typename
E
>
UniGraph
<
V
,
E
>::
UniGraph
(
int
size_
)
:
size
(
size_
)
{
vertices
=
new
Vertex
[
size
];
}
template
<
typename
V
,
typename
E
>
UniGraph
<
V
,
E
>::~
UniGraph
()
noexcept
{
//先按照出边顺序清除表
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
auto
e
=
vertices
[
i
].
outed
;
if
(
e
)
{
auto
e1
=
next_edge
(
i
,
e
);
while
(
e1
)
{
if
(
e
->
v2
>=
0
)
{
//用v2为-1作为已经访问过一次的判据
//注意这个强烈依赖于判定next_edge时仅用了v1!!
e
->
v2
=
-
1
;
}
else
{
delete
e
;
}
e
=
e1
;
e1
=
next_edge
(
i
,
e1
);
}
}
}
delete
[]
vertices
;
vertices
=
nullptr
;
}
//注意 插入到各个边的链表的第一位
template
<
typename
V
,
typename
E
>
typename
UniGraph
<
V
,
E
>::
Edge
*
UniGraph
<
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
].
outed
;
vertices
[
to
].
outed
=
e
;
return
e
;
}
template
<
typename
V
,
typename
E
>
typename
UniGraph
<
V
,
E
>::
Edge
*
UniGraph
<
V
,
E
>::
next_edge
(
int
v
,
Edge
*
e
)
{
if
(
v
==
e
->
v1
)
{
return
e
->
path1
;
}
else
return
e
->
path2
;
}
template
<
typename
V
,
typename
E
>
typename
UniGraph
<
V
,
E
>::
Edge
*&
UniGraph
<
V
,
E
>::
next_edge_ref
(
int
v
,
Edge
*
e
)
{
if
(
v
==
e
->
v1
)
{
return
e
->
path1
;
}
else
return
e
->
path2
;
}
template
<
typename
V
,
typename
E
>
typename
UniGraph
<
V
,
E
>::
Edge
*
UniGraph
<
V
,
E
>::
previous_edge
(
int
v
,
Edge
*
e
)
{
if
(
v
==
e
->
v1
)
{
return
e
->
path2
;
}
else
return
e
->
path1
;
}
template
<
typename
V
,
typename
E
>
typename
UniGraph
<
V
,
E
>::
Edge
*
UniGraph
<
V
,
E
>::
get_edge
(
int
u
,
int
v
)
{
auto
*
e
=
first_edge
(
u
);
for
(;
e
;
e
=
next_edge
(
u
,
e
))
{
if
((
e
->
v1
==
v
&&
e
->
v2
==
u
)
||
(
e
->
v2
==
v
&&
e
->
v1
==
u
))
{
return
e
;
}
}
return
nullptr
;
}
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