-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add 6-10,6-11,6-12,6-13,6-15,6-16,6-17
- Loading branch information
Showing
7 changed files
with
335 additions
and
0 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
Data Structures and Algorithms (English)/6-10_Strongly Connected Components (30).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Helper structure to store DFS information for each vertex | ||
typedef struct { | ||
int dfn; // Discovery time | ||
int low; // Lowest vertex reachable | ||
int inStack; // Whether vertex is in stack | ||
} VertexInfo; | ||
|
||
// Helper function for Tarjan's algorithm | ||
void Tarjan(Graph G, Vertex v, VertexInfo *info, Vertex *stack, int *top, | ||
int *time, void (*visit)(Vertex), int *visited) { | ||
info[v].dfn = info[v].low = (*time)++; | ||
stack[(*top)++] = v; | ||
info[v].inStack = 1; | ||
|
||
PtrToVNode node = G->Array[v]; | ||
while (node) { | ||
Vertex w = node->Vert; | ||
if (info[w].dfn == -1) { // Unvisited vertex | ||
Tarjan(G, w, info, stack, top, time, visit, visited); | ||
if (info[w].low < info[v].low) | ||
info[v].low = info[w].low; | ||
} else if (info[w].inStack) { // Back edge to vertex in stack | ||
if (info[w].dfn < info[v].low) | ||
info[v].low = info[w].dfn; | ||
} | ||
node = node->Next; | ||
} | ||
|
||
// If v is root of SCC, pop stack and print component | ||
if (info[v].dfn == info[v].low) { | ||
Vertex w; | ||
do { | ||
w = stack[--(*top)]; | ||
info[w].inStack = 0; | ||
if (!visited[w]) { | ||
(*visit)(w); | ||
visited[w] = 1; | ||
} | ||
} while (w != v); | ||
printf("\n"); // Print newline after each component | ||
} | ||
} | ||
|
||
void StronglyConnectedComponents(Graph G, void (*visit)(Vertex V)) { | ||
// Initialize arrays | ||
VertexInfo *info = (VertexInfo*)malloc(G->NumOfVertices * sizeof(VertexInfo)); | ||
Vertex *stack = (Vertex*)malloc(G->NumOfVertices * sizeof(Vertex)); | ||
int *visited = (int*)calloc(G->NumOfVertices, sizeof(int)); | ||
int top = 0; // Stack top | ||
int time = 0; // DFS timestamp | ||
|
||
// Initialize vertex info | ||
for (Vertex v = 0; v < G->NumOfVertices; v++) { | ||
info[v].dfn = -1; | ||
info[v].low = -1; | ||
info[v].inStack = 0; | ||
} | ||
|
||
// Run Tarjan's algorithm for each unvisited vertex | ||
for (Vertex v = 0; v < G->NumOfVertices; v++) { | ||
if (info[v].dfn == -1) { | ||
Tarjan(G, v, info, stack, &top, &time, visit, visited); | ||
} | ||
} | ||
|
||
// Free memory | ||
free(info); | ||
free(stack); | ||
free(visited); | ||
} |
35 changes: 35 additions & 0 deletions
35
Data Structures and Algorithms (English)/6-11_Shortest Path [1] (25).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
void ShortestDist(LGraph Graph, int dist[], Vertex S) { | ||
// Initialize queue for BFS | ||
int queue[MaxVertexNum]; | ||
int front = 0, rear = 0; | ||
bool visited[MaxVertexNum] = {false}; | ||
|
||
// Initialize all distances to -1 (unreachable) | ||
for (int i = 0; i < Graph->Nv; i++) { | ||
dist[i] = -1; | ||
} | ||
|
||
// Set distance to source as 0 and enqueue | ||
dist[S] = 0; | ||
queue[rear++] = S; | ||
visited[S] = true; | ||
|
||
// BFS | ||
while (front < rear) { | ||
// Dequeue a vertex | ||
Vertex V = queue[front++]; | ||
|
||
// Traverse all adjacent vertices | ||
PtrToAdjVNode currentNode = Graph->G[V].FirstEdge; | ||
while (currentNode) { | ||
Vertex W = currentNode->AdjV; | ||
if (!visited[W]) { | ||
// Update distance and enqueue | ||
dist[W] = dist[V] + 1; | ||
queue[rear++] = W; | ||
visited[W] = true; | ||
} | ||
currentNode = currentNode->Next; | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
Data Structures and Algorithms (English)/6-12_Shortest Path [2] (25).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
void ShortestDist(MGraph Graph, int dist[], Vertex S) { | ||
bool collected[MaxVertexNum]; | ||
int i; | ||
|
||
// Initialize | ||
for (i = 0; i < Graph->Nv; i++) { | ||
dist[i] = INFINITY; | ||
collected[i] = false; | ||
} | ||
dist[S] = 0; | ||
|
||
while (1) { | ||
// Find the uncollected vertex with smallest distance | ||
Vertex V = -1; | ||
int minDist = INFINITY; | ||
for (i = 0; i < Graph->Nv; i++) { | ||
if (collected[i] == false && dist[i] < minDist) { | ||
V = i; | ||
minDist = dist[i]; | ||
} | ||
} | ||
|
||
// If no such vertex exists, break | ||
if (V == -1) break; | ||
|
||
collected[V] = true; | ||
|
||
// Update dist[] through V | ||
for (i = 0; i < Graph->Nv; i++) { | ||
if (collected[i] == false && Graph->G[V][i] > 0) { | ||
if (dist[V] + Graph->G[V][i] < dist[i]) { | ||
dist[i] = dist[V] + Graph->G[V][i]; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Convert INFINITY to -1 for unreachable vertices | ||
for (i = 0; i < Graph->Nv; i++) { | ||
if (dist[i] == INFINITY) dist[i] = -1; | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
Data Structures and Algorithms (English)/6-13_Topological Sort (25).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
bool TopSort(LGraph Graph, Vertex TopOrder[]) { | ||
int inDegree[MaxVertexNum] = {0}; // Array to store in-degree of each vertex | ||
int count = 0; // Count of vertices in topological order | ||
Vertex queue[MaxVertexNum]; // Queue to store vertices with 0 in-degree | ||
int front = 0, rear = 0; // Queue pointers | ||
|
||
// Calculate in-degree for each vertex | ||
for (int v = 0; v < Graph->Nv; v++) { | ||
PtrToAdjVNode w = Graph->G[v].FirstEdge; | ||
while (w) { | ||
inDegree[w->AdjV]++; | ||
w = w->Next; | ||
} | ||
} | ||
|
||
// Initialize queue with vertices that have 0 in-degree | ||
for (int v = 0; v < Graph->Nv; v++) { | ||
if (inDegree[v] == 0) { | ||
queue[rear++] = v; | ||
} | ||
} | ||
|
||
// Process vertices in queue | ||
while (front < rear) { | ||
Vertex v = queue[front++]; | ||
TopOrder[count++] = v; | ||
|
||
// Decrease in-degree for all adjacent vertices | ||
PtrToAdjVNode w = Graph->G[v].FirstEdge; | ||
while (w) { | ||
if (--inDegree[w->AdjV] == 0) { | ||
queue[rear++] = w->AdjV; | ||
} | ||
w = w->Next; | ||
} | ||
} | ||
|
||
// If count equals number of vertices, topological sort is possible | ||
return count == Graph->Nv; | ||
} |
30 changes: 30 additions & 0 deletions
30
Data Structures and Algorithms (English)/6-15_Iterative Mergesort (25).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
void merge_pass(ElementType list[], ElementType sorted[], int N, int length) { | ||
int i, j, k, a, b; | ||
int start1, end1, start2, end2; | ||
|
||
// Process pairs of sublists | ||
for (i = 0; i < N; i += 2 * length) { | ||
// Define boundaries for first sublist | ||
start1 = i; | ||
end1 = start1 + length < N ? start1 + length : N; | ||
|
||
// Define boundaries for second sublist | ||
start2 = end1; | ||
end2 = start2 + length < N ? start2 + length : N; | ||
|
||
// Merge the two sublists | ||
k = start1; // Starting position in sorted array | ||
a = start1; // Index for first sublist | ||
b = start2; // Index for second sublist | ||
|
||
// Compare and merge elements from both sublists | ||
while (1) | ||
{ | ||
if (a == end1 && b == end2) break; | ||
else if (a == end1) sorted[k++] = list[b++]; | ||
else if (b == end2) sorted[k++] = list[a++]; | ||
else if (list[a] <= list[b]) sorted[k++] = list[a++]; | ||
else sorted[k++] = list[b++]; | ||
} | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
Data Structures and Algorithms (English)/6-16_Shortest Path [3] (25).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
void ShortestDist(MGraph Graph, int dist[], int count[], Vertex S) { | ||
int i; | ||
bool collected[MaxVertexNum]; | ||
|
||
// Initialize | ||
for (i = 0; i < Graph->Nv; i++) { | ||
dist[i] = INFINITY; | ||
count[i] = 0; | ||
collected[i] = false; | ||
} | ||
|
||
// Initialize source vertex | ||
dist[S] = 0; | ||
count[S] = 1; | ||
|
||
while (1) { | ||
// Find the uncollected vertex with minimum distance | ||
int minV = -1; | ||
int minDist = INFINITY; | ||
for (i = 0; i < Graph->Nv; i++) { | ||
if (!collected[i] && dist[i] < minDist) { | ||
minDist = dist[i]; | ||
minV = i; | ||
} | ||
} | ||
|
||
// If no such vertex exists, break | ||
if (minV == -1) break; | ||
|
||
collected[minV] = true; | ||
// Update dist[] and count[] through minV | ||
for (i = 0; i < Graph->Nv; i++) { | ||
if (!collected[i] && Graph->G[minV][i] < INFINITY) { | ||
if (dist[minV] + Graph->G[minV][i] < dist[i]) { | ||
// Found a shorter path | ||
dist[i] = dist[minV] + Graph->G[minV][i]; | ||
count[i] = count[minV]; | ||
} | ||
else if (dist[minV] + Graph->G[minV][i] == dist[i]) { | ||
// Found another shortest path | ||
count[i] += count[minV]; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Convert unreachable vertices' distance to -1 | ||
for (i = 0; i < Graph->Nv; i++) { | ||
if (dist[i] == INFINITY) { | ||
dist[i] = -1; | ||
count[i] = 0; | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
Data Structures and Algorithms (English)/6-17_Shortest Path [4] (25).c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
void ShortestDist(MGraph Graph, int dist[], int path[], Vertex S) { | ||
bool collected[MaxVertexNum]; | ||
int V, W, minV; | ||
WeightType minDist; | ||
|
||
// Initialize | ||
for (V = 0; V < Graph->Nv; V++) { | ||
dist[V] = INFINITY; | ||
path[V] = -1; | ||
collected[V] = false; | ||
} | ||
|
||
// Set source vertex | ||
dist[S] = 0; | ||
|
||
while (1) { | ||
// Find the uncollected vertex with minimum distance | ||
minDist = INFINITY; | ||
minV = -1; | ||
|
||
for (V = 0; V < Graph->Nv; V++) { | ||
if (collected[V] == false && dist[V] < minDist) { | ||
minDist = dist[V]; | ||
minV = V; | ||
} | ||
} | ||
|
||
// If no such vertex exists, break | ||
if (minV == -1) break; | ||
|
||
collected[minV] = true; | ||
|
||
// Update dist[] and path[] through minV | ||
for (W = 0; W < Graph->Nv; W++) { | ||
if (collected[W] == false && Graph->G[minV][W] < INFINITY) { | ||
if (dist[minV] + Graph->G[minV][W] < dist[W]) { | ||
dist[W] = dist[minV] + Graph->G[minV][W]; | ||
path[W] = minV; | ||
} else if (dist[minV] + Graph->G[minV][W] == dist[W] && | ||
GetPathLength(path, minV, S) + 1 < GetPathLength(path, W, S)) { | ||
// If same distance but fewer edges, update path | ||
path[W] = minV; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Convert unreachable vertices' distances to -1 | ||
for (V = 0; V < Graph->Nv; V++) { | ||
if (dist[V] == INFINITY) { | ||
dist[V] = -1; | ||
} | ||
} | ||
} | ||
|
||
// Helper function to count the number of edges in a path | ||
int GetPathLength(int path[], int V, int S) { | ||
int count = 0; | ||
while (V != S && V != -1) { | ||
count++; | ||
V = path[V]; | ||
} | ||
return V == -1 ? INFINITY : count; | ||
} |