本文实例为大家分享了C++数据结构之实现邻接表的具体代码,供大家参考,具体内容如下

一、图的邻接表实现

1.实现了以顶点顺序表、边链表为存储结构的邻接表;

2.实现了图的创建(有向/无向/图/网)、边的增删操作、深度优先递归/非递归遍历、广度优先遍历的算法;

3.采用顶点对象列表、边(弧)对象列表的方式,对图的创建进行初始化;引用 "ObjArrayList.h"头文件,头文件可参看之前博文“数据结构之顺序列表(支持对象元素)”代码;

4.深度优先遍历分别采用递归/非递归算法;非递归中用到的栈,引用"LinkStack.h"头文件,头文件可参看之前博文“数据结构之栈”代码;

5.广度优先遍历采用队列方式实现;用到的队列,引用 "LinkQueue.h"头文件,头文件可参看之前博文“数据结构之队列”代码;

6.测试代码中以有向网的所有带权边作为边的初始化数据,选择图类型(DG, UDG, DN, UDN)可创建成不同类型的图。

7.优劣分析:

7.1.(优势)邻接表存储结构,相比邻接矩阵,消除了无邻接关系顶点的边存储空间;

7.2.(优势)邻接表比邻接矩阵更容易访问某顶点的邻接顶点;

7.3.(优势)邻接表比邻接矩阵更易于统计边总数,无需逐行逐列遍历;

7.4.(劣势)在确定两顶点间是否有边的搜索过程中,邻接表不如邻接矩阵可直接寻址快,反而需要顶点到边链的遍历;

7.5.(劣势)邻接矩阵在删除顶点时,只需清除对应行列数据即可;而邻接表在清除顶点指向的边链后,还需遍历整个边表,清除所有邻接于此顶点的边结点;

7.6.(不足)邻接表在统计有向图出度时容易,只需遍历依附此顶点的边链;却在统计其入度时,需要遍历整个边表,比较麻烦;可采用十字链表(邻接表与逆邻接表的结合)解决这个问题;

7.7.(不足)邻接表在无向图的存储中,属于行列对称矩阵形式,因此会有一半重复的边数据,故可采用邻接多重表,只存储一半边,来优化存储。

二、测试代码中的图结构

深度优先遍历序列(从 v1 顶点开始):

1.无向图/网:v1-v2-v3-v5-v4-v6-v7

2.有向图/网:v1-v2-v5-v3-v4-v6-v7

广度优先遍历序列(从 v2 顶点开始):

1.无向图/网:v2-v1-v3-v5-v4-v6-v7

2.有向图/网:v2-v5 后序无法遍历

注:有向图的遍历 是遵循出度方向遍历的,若无出度方向,则遍历终止。

三、代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

//文件名:"GraphAdjList.h"

#pragma once

#ifndef GRAPHADJLISL_H_

#define GRAPHADJLISL_H_

  

#include <string>

#include "ObjArrayList.h"

using namespace std;

  

/*

. 图(邻接表实现) Graph Adjacency List

. 相关术语:

. 顶点 Vertex ; 边 Arc ;权 Weight ;

. 有向图 Digraph ;无向图 Undigraph ;

. 有向网 Directed Network ;无向网 Undirected Network ;

. 存储结构:

. 1.顶点表只能采用顺序结构。(因为若采用链式结构,顶点结点定义与边表结点定义就相互引用,无法定义)

. 2.边表采用链表结构。

*/

  

class GraphAdjList

{

 /*

 . 边表(链表)结点

 */

 struct ArcNode

 {

 int adjVex; //邻接顶点所在表中下标

 int weight; //边权重

 ArcNode * next; //下一条边

 };

 /*

 . 顶点表(顺序表)结点

 */

 struct VNode

 {

 string name; //顶点名

 ArcNode * first; //指向的第一个依附该顶点的顶点边结点

 };

public:

 /*

 . 图 种类

 */

 enum GraphType

 {

 DG, //有向图,默认 0

 UDG, //无向图,默认 1

 DN, //有向网,默认 2

 UDN //无向网,默认 3

 };

 /*

 . 边(弧)数据,注:供外部初始化边数据使用

 */

 struct ArcData

 {

 string Tail; //弧尾

 string Head; //弧头

 int Weight; //权重

 };

  

private:

 static const int _MAX_VERTEX_NUM = 10; //支持最大顶点数

  

 VNode vexs[_MAX_VERTEX_NUM]; //顶点表

 int vexs_visited[_MAX_VERTEX_NUM]; //顶点访问标记数组:0|未访问 1|已访问

 int vexNum; //顶点数

 int arcNum; //边数

 int type; //图种类

  

 void _CreateVexSet(ObjArrayList<string> * vexs); //创建顶点集合

 void _CreateDG(ObjArrayList<ArcData> * arcsList); //创建有向图

 void _CreateUDG(ObjArrayList<ArcData> * arcsList); //创建无向图

 void _CreateDN(ObjArrayList<ArcData> * arcsList); //创建有向网

 void _CreateUDN(ObjArrayList<ArcData> * arcsList); //创建无向网

  

 int _Locate(string vertex);   //定位顶点元素位置

 void _InsertArc(int tail, int head, int weight); //插入边(元操作,不分有向/无向)

 void _DeleteArc(int tail, int head);  //删除边(元操作,不分有向/无向)

 void _DFS_R(int index);   //深度优先遍历 递归

 void _DFS(int index);   //深度优先遍历 非递归

  

public:

 GraphAdjList(int type); //构造函数:初始化图种类

 ~GraphAdjList();  //析构函数

 void Init(ObjArrayList<string> * vexs, ObjArrayList<ArcData> * arcsList); //初始化顶点、边数据为 图|网

 void InsertArc(ArcData * arcData); //插入边(含有向/无向操作)

 void DeleteArc(ArcData * arcData); //删除边(含有向/无向操作)

 void Display();  //显示 图|网

 void Display_DFS_R(string *vertex); //从指定顶点开始,深度优先 递归 遍历

 void Display_DFS(string *vertex); //从指定顶点开始,深度优先 非递归 遍历

 void Display_BFS(string *vertex); //从指定顶点开始,广度优先遍历

  

};

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

//文件名:"GraphAdjList.cpp"

#include "stdafx.h"

#include <string>

#include "ObjArrayList.h"

#include "LinkQueue.h"

#include "LinkStack.h"

#include "GraphAdjList.h"

using namespace std;

  

GraphAdjList::GraphAdjList(int type)

{

 /*

 . 构造函数:初始化图类型

 */

 this->type = type;

 this->vexNum = 0;

 this->arcNum = 0;

}

  

GraphAdjList::~GraphAdjList()

{

 /*

 . 析构函数:销毁图

 */

}

  

void GraphAdjList::Init(ObjArrayList<string> * vexs, ObjArrayList<ArcData> * arcsList)

{

 /*

 . 初始化顶点、边数据,并构建 图|网

 . 入参:

 . vexs: 顶点 列表

 . arcsList: 边数据 列表

 */

 //1.创建顶点集

 _CreateVexSet(vexs);

 //2.根据图类型,创建指定的图

 switch (this->type)

 {

 case DG:

 _CreateDG(arcsList); break;

 case UDG:

 _CreateUDG(arcsList); break;

 case DN:

 _CreateDN(arcsList); break;

 case UDN:

 _CreateUDN(arcsList); break;

 default:

 break;

 }

}

  

void GraphAdjList::_CreateVexSet(ObjArrayList<string> * vexs)

{

 /*

 . 创建顶点集合

 */

 string vertex = "";

 //顶点最大数校验

 if (vexs->Length() > this->_MAX_VERTEX_NUM)

 {

 return;

 }

 //遍历顶点表,无重复插入顶点,并计数顶点数

 for (int i = 0; i < vexs->Length(); i++)

 {

 vertex = *vexs->Get(i);

 if (_Locate(vertex) == -1)

 {

 this->vexs[this->vexNum].name = vertex;

 this->vexs[this->vexNum].first = NULL;

 this->vexNum++;

 }

 }

}

  

void GraphAdjList::_CreateDG(ObjArrayList<ArcData> * arcsList)

{

 /*

 . 创建有向图

 . 邻接矩阵为 非对称边

 */

 //初始化临时 边对象

 ArcData * arcData = NULL;

 //初始化 Tail Head 顶点下标索引

 int tail = 0, head = 0;

 //遍历边数据列表

 for (int i = 0; i < arcsList->Length(); i++)

 {

 //按序获取边(弧)

 arcData = arcsList->Get(i);

 //定位(或设置)边的两端顶点位置

 tail = _Locate(arcData->Tail);

 head = _Locate(arcData->Head);

 //插入边

 _InsertArc(tail, head, 0);

 }

}

  

void GraphAdjList::_CreateUDG(ObjArrayList<ArcData> * arcsList)

{

 /*

 . 创建无向图

 . 邻接矩阵为 对称边

 */

 //初始化临时 边对象

 ArcData * arcData = NULL;

 //初始化 Tail Head 顶点下标索引

 int tail = 0, head = 0;

 //遍历边数据列表

 for (int i = 0; i < arcsList->Length(); i++)

 {

 //按序获取边(弧)

 arcData = arcsList->Get(i);

 //定位(或设置)边的两端顶点位置

 tail = _Locate(arcData->Tail);

 head = _Locate(arcData->Head);

 //插入对称边

 _InsertArc(tail, head, 0);

 _InsertArc(head, tail, 0);

 }

}

  

void GraphAdjList::_CreateDN(ObjArrayList<ArcData> * arcsList)

{

 /*

 . 创建有向网

 . 邻接矩阵为 非对称矩阵

 */

 //初始化临时 边对象

 ArcData * arcData = NULL;

 //初始化 Tail Head 顶点下标索引

 int tail = 0, head = 0;

 //遍历边数据列表

 for (int i = 0; i < arcsList->Length(); i++)

 {

 //按序获取边(弧)

 arcData = arcsList->Get(i);

 //定位(或设置)边的两端顶点位置

 tail = _Locate(arcData->Tail);

 head = _Locate(arcData->Head);

 //插入边

 _InsertArc(tail, head, arcData->Weight);

 }

}

  

void GraphAdjList::_CreateUDN(ObjArrayList<ArcData> * arcsList)

{

 /*

 . 创建无向网

 . 邻接矩阵为 对称矩阵

 */

 //初始化临时 边对象

 ArcData * arcData = NULL;

 //初始化 Tail Head 顶点下标索引

 int tail = 0, head = 0;

 //遍历边数据列表

 for (int i = 0; i < arcsList->Length(); i++)

 {

 //按序获取边(弧)

 arcData = arcsList->Get(i);

 //定位(或设置)边的两端顶点位置

 tail = _Locate(arcData->Tail);

 head = _Locate(arcData->Head);

 //插入对称边

 _InsertArc(tail, head, arcData->Weight);

 _InsertArc(head, tail, arcData->Weight);

 }

}

  

int GraphAdjList::_Locate(string vertex)

{

 /*

 . 定位顶点元素位置

 . 后期可改成【字典树】,顶点数超过100个后定位顶点位置可更快

 */

 //遍历定位顶点位置

 for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)

 {

 if (vertex == this->vexs[i].name)

 {

 return i;

 }

 }

 //cout << endl << "顶点[" << vertex << "]不存在。" << endl;

 return -1;

}

  

void GraphAdjList::_InsertArc(int tail, int head, int weight)

{

 /*

 . 插入边(元操作,不分有向/无向)

 */

 //边结点指针:初始化为 弧尾 指向的第一个边

 ArcNode * p = this->vexs[tail].first;

 //初始化 前一边结点的指针

 ArcNode * q = NULL;

 //重复边布尔值

 bool exist = false;

 //1.边的重复性校验

 while (p != NULL)

 {

 //若已存在该边,则标记为 存在 true

 if (p->adjVex == head)

 {

 exist = true;

 break;

 }

 //若不是该边,继续下一个边校验

 q = p;

 p = p->next;

 }

 //2.1.如果边存在,则跳过,不做插入

 if (exist)

 return;

 //2.2.边不存在时,创建边

 ArcNode * newArc = new ArcNode();

 newArc->adjVex = head;

 newArc->weight = weight;

 newArc->next = NULL;

 //3.1.插入第一条边

 if (q == NULL)

 {

 this->vexs[tail].first = newArc;

 }

 //3.2.插入后序边

 else

 {

 q->next = newArc;

 }

 //4.边 计数

 this->arcNum++;

}

  

void GraphAdjList::InsertArc(ArcData * arcData)

{

 /*

 . 插入边(含有向/无向操作)

 */

 //初始化 Tail Head 顶点下标索引

 int tail = 0, head = 0;

 tail = _Locate(arcData->Tail);

 head = _Locate(arcData->Head);

 //根据图类型,插入边

 switch (this->type)

 {

 case DG:

 _InsertArc(tail, head, 0);

 break;

 case UDG:

 _InsertArc(tail, head, 0);

 _InsertArc(head, tail, 0);

 break;

 case DN:

 _InsertArc(tail, head, arcData->Weight);

 break;

 case UDN:

 _InsertArc(tail, head, arcData->Weight);

 _InsertArc(head, tail, arcData->Weight);

 break;

 default:

 break;

 }

}

  

void GraphAdjList::_DeleteArc(int tail, int head)

{

 /*

 . 删除边(元操作,不分有向/无向)

 */

 //边结点指针:初始化为 弧尾 指向的第一个边

 ArcNode * p = this->vexs[tail].first;

 //初始化 前一边结点的指针

 ArcNode * q = NULL;

 //1.遍历查找边

 while (p != NULL)

 {

 //若存在该边,则结束循环

 if (p->adjVex == head)

 {

 break;

 }

 //若不是该边,继续下一个边

 q = p;

 p = p->next;

 }

 //2.1.边不存在

 if (p == NULL)

 {

 cout << endl << "边[" << this->vexs[head].name << "->" << this->vexs[head].name << "]不存在。" << endl;

 return;

 }

 //2.2.边存在,删除边

 //2.2.1.若为第一条边

 if (q == NULL)

 {

 this->vexs[tail].first = p->next;

 }

 //2.2.2.非第一条边

 else

 {

 q->next = p->next;

 }

 //3.释放 p

 delete p;

}

  

void GraphAdjList::DeleteArc(ArcData * arcData)

{

 /*

 . 删除边(含有向/无向操作)

 */

 //初始化 Tail Head 顶点下标索引

 int tail = 0, head = 0;

 tail = _Locate(arcData->Tail);

 head = _Locate(arcData->Head);

 //根据图类型,删除边

 switch (this->type)

 {

 case DG:

 _DeleteArc(tail, head);

 break;

 case UDG:

 _DeleteArc(tail, head);

 _DeleteArc(head, tail);

 break;

 case DN:

 _DeleteArc(tail, head);

 break;

 case UDN:

 _DeleteArc(tail, head);

 _DeleteArc(head, tail);

 break;

 default:

 break;

 }

}

  

void GraphAdjList::Display()

{

 /*

 . 显示 图|网

 */

 //初始化边表结点指针

 ArcNode * p = NULL;

 cout << endl << "邻接表:" << endl;

 //遍历顶点表

 for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)

 {

 //空顶点(在删除顶点的操作后会出现此类情况)

 if (this->vexs[i].name == "")

 {

 continue;

 }

 //输出顶点

 cout << "[" << i << "]" << this->vexs[i].name << " ";

 //遍历输出边顶点

 p = this->vexs[i].first;

 while (p != NULL)

 {

 cout << "[" << p->adjVex << "," << p->weight << "] ";

 p = p->next;

 }

 cout << endl;

 }

}

  

void GraphAdjList::_DFS_R(int index)

{

 /*

 . 深度优先遍历 递归

 */

 //1.访问顶点,并标记已访问

 cout << this->vexs[index].name << " ";

 this->vexs_visited[index] = 1;

 //2.遍历访问其相邻顶点

 ArcNode * p = this->vexs[index].first;

 int adjVex = 0;

 while (p != NULL)

 {

 adjVex = p->adjVex;

 //当顶点未被访问过时,可访问

 if (this->vexs_visited[adjVex] != 1)

 {

 _DFS_R(adjVex);

 }

 p = p->next;

 }

}

  

void GraphAdjList::Display_DFS_R(string *vertex)

{

 /*

 . 从指定顶点开始,深度优先 递归 遍历

 */

 //1.判断顶点是否存在

 int index = _Locate(*vertex);

 if (index == -1)

 return;

 //2.初始化顶点访问数组

 for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)

 {

 this->vexs_visited[i] = 0;

 }

 //3.深度优先遍历 递归

 cout << "深度优先遍历(递归):(从顶点" << *vertex << "开始)" << endl;

 _DFS_R(index);

}

  

void GraphAdjList::_DFS(int index)

{

 /*

 . 深度优先遍历 非递归

 */

 //1.访问第一个结点,并标记为 已访问

 cout << this->vexs[index].name << " ";

 vexs_visited[index] = 1;

 //初始化 边结点 栈

 LinkStack<ArcNode> * s = new LinkStack<ArcNode>();

 //初始化边结点 指针

 ArcNode * p = this->vexs[index].first;

 //2.寻找下一个(未访问的)邻接结点

 while (!s->Empty() || p != NULL)

 {

 //2.1.未访问过,则访问 (纵向遍历)

 if (vexs_visited[p->adjVex] != 1)

 {

 //访问结点,标记为访问,并将其入栈

 cout << this->vexs[p->adjVex].name << " ";

 vexs_visited[p->adjVex] = 1;

 s->Push(p);

 //指针 p 移向 此结点的第一个邻接结点

 p = this->vexs[p->adjVex].first;

 }

 //2.2.已访问过,移向下一个边结点 (横向遍历)

 else

 p = p->next;

 //3.若无邻接点,则返回上一结点层,并出栈边结点

 if (p == NULL)

 {

 p = s->Pop();

 }

 }

 //释放 栈

 delete s;

}

  

void GraphAdjList::Display_DFS(string *vertex)

{

 /*

 . 从指定顶点开始,深度优先 非递归 遍历

 */

 //1.判断顶点是否存在

 int index = _Locate(*vertex);

 if (index == -1)

 return;

 //2.初始化顶点访问数组

 for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)

 {

 this->vexs_visited[i] = 0;

 }

 //3.深度优先遍历 递归

 cout << "深度优先遍历(非递归):(从顶点" << *vertex << "开始)" << endl;

 _DFS(index);

}

  

void GraphAdjList::Display_BFS(string *vertex)

{

 /*

 . 从指定顶点开始,广度优先遍历

 */

 //1.判断顶点是否存在

 int index = _Locate(*vertex);

 if (index == -1)

 return;

 //2.初始化顶点访问数组

 for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)

 {

 this->vexs_visited[i] = 0;

 }

 //3.广度优先遍历

 cout << "广度优先遍历:(从顶点" << *vertex << "开始)" << endl;

 //3.1.初始化队列

 LinkQueue<int> * vexQ = new LinkQueue<int>();

 //3.2.访问开始顶点,并标记访问、入队

 cout << this->vexs[index].name << " ";

 this->vexs_visited[index] = 1;

 vexQ->EnQueue(new int(index));

 //3.3.出队,并遍历邻接顶点(下一层次),访问后入队

 ArcNode * p = NULL;

 int adjVex = 0;

 while (vexQ->GetHead() != NULL)

 {

 index = *vexQ->DeQueue();

 p = this->vexs[index].first;

 //遍历邻接顶点

 while (p != NULL)

 {

 adjVex = p->adjVex;

 //未访问过的邻接顶点

 if (this->vexs_visited[adjVex] != 1)

 {

 //访问顶点,并标记访问、入队

 cout << this->vexs[adjVex].name << " ";

 this->vexs_visited[adjVex] = 1;

 vexQ->EnQueue(new int(adjVex));

 }

 p = p->next;

 }

 }

  

 //4.释放队列

 int * e;

 while (vexQ->GetHead() != NULL)

 {

 e = vexQ->DeQueue();

 delete e;

 }

 delete vexQ;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

//文件名:"GraphAdjList_Test.cpp"

#include "stdafx.h"

#include <iostream>

#include "GraphAdjList.h"

#include "ObjArrayList.h"

using namespace std;

  

int main()

{

 //初始化顶点数据

 string * v1 = new string("v1");

 string * v2 = new string("v2");

 string * v3 = new string("v3");

 string * v4 = new string("v4");

 string * v5 = new string("v5");

 string * v6 = new string("v6");

 string * v7 = new string("v7");

 ObjArrayList<string> * vexs = new ObjArrayList<string>();

 vexs->Add(v1);

 vexs->Add(v2);

 vexs->Add(v3);

 vexs->Add(v4);

 vexs->Add(v5);

 vexs->Add(v6);

 vexs->Add(v7);

  

 //初始化边(弧)数据

 GraphAdjList::ArcData * arc1 = new GraphAdjList::ArcData{ "v1", "v2", 2 };

 GraphAdjList::ArcData * arc2 = new GraphAdjList::ArcData{ "v1", "v3", 3 };

 GraphAdjList::ArcData * arc3 = new GraphAdjList::ArcData{ "v1", "v4", 4 };

 GraphAdjList::ArcData * arc4 = new GraphAdjList::ArcData{ "v3", "v1", 5 };

 GraphAdjList::ArcData * arc5 = new GraphAdjList::ArcData{ "v3", "v2", 6 };

 GraphAdjList::ArcData * arc6 = new GraphAdjList::ArcData{ "v3", "v5", 7 };

 GraphAdjList::ArcData * arc7 = new GraphAdjList::ArcData{ "v2", "v5", 8 };

 GraphAdjList::ArcData * arc8 = new GraphAdjList::ArcData{ "v4", "v6", 9 };

 GraphAdjList::ArcData * arc9 = new GraphAdjList::ArcData{ "v4", "v7", 9 };

 GraphAdjList::ArcData * arc10 = new GraphAdjList::ArcData{ "v6", "v7", 9 };

 ObjArrayList<GraphAdjList::ArcData> * arcsList = new ObjArrayList<GraphAdjList::ArcData>();

 arcsList->Add(arc1);

 arcsList->Add(arc2);

 arcsList->Add(arc3);

 arcsList->Add(arc4);

 arcsList->Add(arc5);

 arcsList->Add(arc6);

 arcsList->Add(arc7);

 arcsList->Add(arc8);

 arcsList->Add(arc9);

 arcsList->Add(arc10);

  

 //测试1:无向图

 cout << endl << "无向图初始化:" << endl;

 GraphAdjList * udg = new GraphAdjList(GraphAdjList::UDG);

 udg->Init(vexs, arcsList);

 udg->Display();

 //1.1.深度优先遍历

 cout << endl << "无向图深度优先遍历序列:(递归)" << endl;

 udg->Display_DFS_R(v1);

 cout << endl << "无向图深度优先遍历序列:(非递归)" << endl;

 udg->Display_DFS(v1);

 //1.2.广度优先遍历

 cout << endl << "无向图广度优先遍历序列:" << endl;

 udg->Display_BFS(v2);

 //1.3.插入新边

 cout << endl << "无向图新边:" << endl;

 udg->InsertArc(new GraphAdjList::ArcData{ "v7", "v1", 8 });

 udg->Display();

 //1.4.删除边

 cout << endl << "无向图删除边arc9:" << endl;

 udg->DeleteArc(arc9);

 udg->Display();

  

 //测试2:有向图

 cout << endl << "有向图:" << endl;

 GraphAdjList * dg = new GraphAdjList(GraphAdjList::DG);

 dg->Init(vexs, arcsList);

 dg->Display();

 //2.1.深度优先遍历

 cout << endl << "有向图深度优先遍历序列:(递归)" << endl;

 dg->Display_DFS_R(v1);

 cout << endl << "有向图深度优先遍历序列:(非递归)" << endl;

 dg->Display_DFS(v1);

 //2.2.广度优先遍历

 cout << endl << "有向图广度优先遍历序列:" << endl;

 dg->Display_BFS(v2);

  

 //测试:无向网

 cout << endl << "无向网:" << endl;

 GraphAdjList * udn = new GraphAdjList(GraphAdjList::UDN);

 udn->Init(vexs, arcsList);

 udn->Display();

  

 //测试:有向网

 cout << endl << "有向网:" << endl;

 GraphAdjList * dn = new GraphAdjList(GraphAdjList::DN);

 dn->Init(vexs, arcsList);

 dn->Display();

  

 return 0;

}

以上就是本文的全部内容,希望对大家的学习有所帮助,

更多推荐