1 | import LinkList from "../linklist/LinkList";
|
2 | import { toString } from "../util";
|
3 | import { GraphEdge } from "./GraphEdge";
|
4 |
|
5 | export class GraphVertex<T = string>{
|
6 | private node: T;
|
7 | private key: string;
|
8 |
|
9 | private edges: LinkList<GraphEdge<T>>;
|
10 | private indegree = 0;
|
11 |
|
12 | public set InDegree(value: number){
|
13 | this.indegree = value;
|
14 | }
|
15 |
|
16 | public get Key(){
|
17 | return this.key;
|
18 | }
|
19 |
|
20 | public get Node(){
|
21 | return this.node;
|
22 | }
|
23 |
|
24 | public get Property(){
|
25 | return this.property;
|
26 | }
|
27 |
|
28 | constructor(node: T , private property ?: keyof T){
|
29 | if (property){
|
30 | const key = node[property];
|
31 | this.key = toString(key);
|
32 | }else{
|
33 | this.key = toString(node);
|
34 | }
|
35 | this.node = node;
|
36 | this.edges = new LinkList();
|
37 | }
|
38 |
|
39 | public addUndirectedEdge(endVertex: GraphVertex<T>, weight?: number){
|
40 | if (!endVertex){
|
41 | throw new Error("end vertex is not empty");
|
42 | }
|
43 | const exist = this.edges.findNode(item => item.EndVertex.Key === endVertex.Key);
|
44 | if (exist){
|
45 | return false;
|
46 | }
|
47 | const edge = new GraphEdge(this , endVertex , weight);
|
48 | this.edges.append(edge);
|
49 | endVertex.addUndirectedEdge(this , weight);
|
50 | }
|
51 |
|
52 | public addEdge(endVertex: GraphVertex<T>, weight?: number){
|
53 | if (!endVertex){
|
54 | throw new Error("end vertex is not empty");
|
55 | }
|
56 | const exist = this.edges.findNode(item => item.EndVertex.Key === endVertex.Key);
|
57 | if (exist){
|
58 | return false;
|
59 | }
|
60 | const edge = new GraphEdge(this , endVertex , weight);
|
61 | this.edges.append(edge);
|
62 | endVertex.InDegree = endVertex.getInDegree() + 1;
|
63 | return true;
|
64 | }
|
65 |
|
66 | public getEdges(){
|
67 | return this.edges;
|
68 | }
|
69 |
|
70 | public getEdge(endKey: string){
|
71 | const edge = this.edges.findNode(item => item.EndVertex.Key === endKey);
|
72 | if (edge){
|
73 | return edge.Value;
|
74 | }
|
75 | return null;
|
76 | }
|
77 |
|
78 | public deleteEdgeByKey(endKey: string, directed = true){
|
79 | const edge = this.edges.findNode(item => item.EndVertex.key === endKey);
|
80 | const success = this.edges.deleteNode(item => item.EndVertex.Key === endKey);
|
81 | if (success){
|
82 | if (directed){
|
83 | edge.Value.EndVertex.InDegree = edge.Value.EndVertex.getInDegree() - 1;
|
84 | }else{
|
85 | edge.Value.EndVertex.deleteEdgeByKey(edge.Value.StartVertex.key , true);
|
86 | }
|
87 | }
|
88 | return success;
|
89 | }
|
90 |
|
91 | public deleteEdge(edge: GraphEdge<T>){
|
92 | const success = this.edges.deleteNode(edge);
|
93 | if (success){
|
94 | edge.EndVertex.InDegree = edge.EndVertex.getInDegree() - 1;
|
95 | }
|
96 | return success;
|
97 | }
|
98 |
|
99 | public hasEdge(){
|
100 | return !!this.edges.Size;
|
101 | }
|
102 |
|
103 | public getInDegree(){
|
104 | return this.indegree;
|
105 | }
|
106 |
|
107 | public getOutDegree(){
|
108 | return this.edges.Size;
|
109 | }
|
110 |
|
111 | public getDegree(){
|
112 | return this.getInDegree() + this.getOutDegree();
|
113 | }
|
114 |
|
115 | |
116 |
|
117 |
|
118 | public getNeighbors() {
|
119 | const arr: Array<GraphVertex<T>> = [];
|
120 | let node = this.edges.getHeadNode();
|
121 | while (node){
|
122 | arr.push(node.Value.EndVertex);
|
123 | node = node.Next;
|
124 | }
|
125 | return arr;
|
126 | }
|
127 | }
|