图的创建及输出(要求:所有图的创建及输出,即无向图、有向图、无向网、有向网);
图的创建及遍历(要求:DFS和BFS);
在图创建的基础上实现图的基本运算(参考教材相关实例,编程能力强的同学可做图的相关应用算法);
有序表的二分查找(要求:递归和非递归两种方式实现;设计相应的查找成功和查找不成功的测试案例;输出比较元素和比较次数)
以下是使用Python实现图的创建、遍历和基本运算的示例代码:
# 图的创建及输出
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.adj_matrix = [[0] * vertices for _ in range(vertices)]
def add_edge(self, src, dest):
self.adj_matrix[src][dest] = 1
self.adj_matrix[dest][src] = 1
def print_graph(self):
for row in self.adj_matrix:
print(row)
# 图的遍历(DFS和BFS)
def dfs(graph, start, visited):
visited[start] = True
print(start, end=" ")
for i in range(graph.vertices):
if graph.adj_matrix[start][i] == 1 and not visited[i]:
dfs(graph, i, visited)
def bfs(graph, start):
visited = [False] * graph.vertices
queue = []
visited[start] = True
queue.append(start)
while queue:
vertex = queue.pop(0)
print(vertex, end=" ")
for i in range(graph.vertices):
if graph.adj_matrix[vertex][i] == 1 and not visited[i]:
visited[i] = True
queue.append(i)
# 图的基本运算
def get_indegree(graph, vertex):
indegree = 0
for i in range(graph.vertices):
if graph.adj_matrix[i][vertex] == 1:
indegree += 1
return indegree
def get_outdegree(graph, vertex):
outdegree = 0
for i in range(graph.vertices):
if graph.adj_matrix[vertex][i] == 1:
outdegree += 1
return outdegree
# 创建一个无向图并输出
g = Graph(5)
g.add_edge(0, 1)
g.add_edge(0, 4)
g.add_edge(1, 2)
g.add_edge(1, 3)
g.add_edge(1, 4)
g.add_edge(2, 3)
g.add_edge(3, 4)
print("无向图的邻接矩阵:")
g.print_graph()
# DFS遍历无向图
print("DFS遍历无向图:")
visited = [False] * g.vertices
dfs(g, 0, visited)
print()
# BFS遍历无向图
print("BFS遍历无向图:")
bfs(g, 0)
print()
# 获取无向图中某个顶点的入度和出度
vertex = 2
print(f"顶点{vertex}的入度为:{get_indegree(g, vertex)}")
print(f"顶点{vertex}的出度为:{get_outdegree(g, vertex)}")
对于有向图和带权图的创建和操作,可以根据需要进行相应的修改和扩展。
至于有序表的二分查找,以下是使用递归和非递归两种方式实现的示例代码:
# 递归实现有序表的二分查找
def binary_search_recursive(arr, low, high, target):
if low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search_recursive(arr, mid + 1, high, target)
else:
return binary_search_recursive(arr, low, mid - 1, target)
else:
return -1
# 非递归实现有序表的二分查找
def binary_search_iterative(arr, target):
low = 0
high = len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
# 测试有序表的二分查找
arr = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
target = 12
# 递归方式查找
index_recursive = binary_search_recursive(arr, 0, len(arr) - 1, target)
if index_recursive != -1:
print(f"递归方式:元素{target}在索引{index_recursive}处找到")
else:
print(f"递归方式:元素{target}未找到")
# 非递归方式查找
index_iterative = binary_search_iterative(arr, target)
if index_iterative != -1:
print(f"非递归方式:元素{target}在索引{index_iterative}处找到")
else:
print(f"非递归方式:元素{target}未找到")
以上代码演示了如何创建图、进行遍历和基本运算,以及如何实现有图的相关应用算法。以下是一个示例,展示如何使用图来实现最短路径算法(Dijkstra算法):
import sys
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.adj_matrix = [[0] * vertices for _ in range(vertices)]
def add_edge(self, src, dest, weight):
self.adj_matrix[src][dest] = weight
self.adj_matrix[dest][src] = weight
def dijkstra(self, src):
visited = [False] * self.vertices
distance = [sys.maxsize] * self.vertices
distance[src] = 0
for _ in range(self.vertices):
min_distance = sys.maxsize
min_vertex = -1
for v in range(self.vertices):
if not visited[v] and distance[v] < min_distance:
min_distance = distance[v]
min_vertex = v
visited[min_vertex] = True
for v in range(self.vertices):
if (
self.adj_matrix[min_vertex][v] > 0
and not visited[v]
and distance[v] > distance[min_vertex] + self.adj_matrix[min_vertex][v]
):
distance[v] = distance[min_vertex] + self.adj_matrix[min_vertex][v]
return distance
# 创建一个有向网并输出
g = Graph(6)
g.add_edge(0, 1, 2)
g.add_edge(0, 2, 4)
g.add_edge(1, 2, 1)
g.add_edge(1, 3, 7)
g.add_edge(2, 4, 3)
g.add_edge(3, 4, 2)
g.add_edge(3, 5, 1)
g.add_edge(4, 5, 5)
print("有向网的邻接矩阵:")
for row in g.adj_matrix:
print(row)
# 使用Dijkstra算法计算最短路径
src_vertex = 0
distances = g.dijkstra(src_vertex)
print(f"从顶点{src_vertex}到其他顶点的最短路径:")
for v in range(g.vertices):
print(f"顶点{src_vertex}到顶点{v}的最短距离为:{distances[v]}")
以上代码演示了如何使用图来实现最短路径算法(Dijkstra算法)。你可以根据需要进行修改和扩展,实现其他图的相关应用算法。
【由 http://www.gpt100.chat/ 生成,人工整理】
问题解答:
创建并输出图形,包括无向图、有向图、无向网和有向网:
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 1000;
int n, m;
int g[MAXN][MAXN];
int main(){
cin >> n >> m;
memset(g, 0, sizeof(g)); //初始化全局数组全部为0
for(int i = 0; i < m; i++){
int a, b;
cin >> a >> b;
g[a][b] = 1;
g[b][a] = 1; //无向图定义是双向的
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cout << g[i][j] << " ";
}
cout << endl; //每输出一行要换行
}
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
const int MAXN = 1000;
int n, m;
vector<int> adj[MAXN]; //使用vector类型数组定义邻接表
int main(){
cin >> n >> m;
for(int i = 0; i < m; i++){
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a); //双向定义,两个端点同时作为vector数组的下标
}
for(int i = 0; i < n; i++){
for(int j = 0; j < adj[i].size(); j++){ //遍历每个vector下的数值
cout << adj[i][j] << " ";
}
cout << endl;
}
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 1000;
const int INF = 10000; //定义一个极大值
int n, m;
int g[MAXN][MAXN];
int main(){
cin >> n >> m;
memset(g, INF, sizeof(g)); //初始化全局数组全部为INF
for(int i = 0; i < m; i++){
int a, b, w;
cin >> a >> b >> w;
g[a][b] = w;
g[b][a] = w; //无向网定义是双向的
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(g[i][j] == INF){ //如果两点不连通
cout << "INF" << " ";
}
else{
cout << g[i][j] << " ";
}
}
cout << endl;
}
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 1000;
const int INF = 10000; //定义一个极大值
int n, m;
int g[MAXN][MAXN];
int main(){
cin >> n >> m;
memset(g, INF, sizeof(g)); //初始化全局数组全部为INF
for(int i = 0; i < m; i++){
int a, b, w;
cin >> a >> b >> w;
g[a][b] = w;
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(g[i][j] == INF){ //如果两点不连通
cout << "INF" << " ";
}
else{
cout << g[i][j] << " ";
}
}
cout << endl;
}
return 0;
}
图的遍历,包括DFS和BFS:
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 1000;
bool visited[MAXN] = {false}; //visited数组初始全部为false
int n, m;
int g[MAXN][MAXN];
void DFS(int u){
visited[u] = true;
for(int v = 0; v < n; v++){
if(g[u][v] != 0 && !visited[v]){ //如果两点连通并且未访问
DFS(v);
}
}
}
int main(){
cin >> n >> m;
memset(g, 0, sizeof(g));
for(int i = 0; i < m; i++){
int a, b;
cin >> a >> b;
g[a][b] = 1;
g[b][a] = 1;
}
for(int i = 0; i < n; i++){
if(!visited[i]){ //如果该点未被访问,从该点开始访问
DFS(i);
}
}
return 0;
}
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 1000;
bool visited[MAXN] = {false}; //visited数组初始全部为false
int n, m;
int g[MAXN][MAXN];
void BFS(int u){
queue<int> q; //使用队列
q.push(u);
visited[u] = true;
while(!q.empty()){
int front = q.front();
q.pop();
for(int v = 0; v < n; v++){
if(g[front][v] != 0 && !visited[v]){ //如果两点连通并且沿路访问的点未访问过
q.push(v);
visited[v] = true;
}
}
}
}
int main(){
cin >> n >> m;
memset(g, 0, sizeof(g));
for(int i = 0; i < m; i++){
int a, b;
cin >> a >> b;
g[a][b] = 1;
g[b][a] = 1;
}
for(int i = 0; i < n; i++){
if(!visited[i]){ //如果该点未被访问,从该点开始BFS
BFS(i);
}
}
return 0;
}
图的基本运算:
在无向图中,我们可以直接使用BFS或DFS进行连通性判断,遍历过程中只要发现有未访问过的点就从该点开始进行遍历