用c写的邻接链表(或邻接矩阵)存储,栈(或队列)实现的拓扑排序。
#include
#include
#define STACK_INIT_SIZE 100
#define VNUM 100
#define STACKINCREMENT 10
#define OVERFLOW 0
#define ERROR 0
#define OK 1
#define MAX_VERTEX_NUM 20
typedef int Status;
typedef char VertexType;
typedef struct ArcNode //邻接链表
{
int adjvex;//该弧所指向的顶点的位置
struct ArcNode* nextarc;//指向下一条弧的指针
}ArcNode;
typedef struct VNode
{
VertexType data;
ArcNode* firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices;
int vexnum, arcnum;
}ALGraph;
typedef struct {
VertexType vexs[MAX_VERTEX_NUM];
Status arcs[VNUM][VNUM];
int vexnum, arcnum;
}MGraph;//邻接矩阵
typedef struct
{
int* base;
int* top;
int stacksize;
}Sqstack;
typedef struct QNode {
int data;
struct QNode* next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;
Status InitStack(Sqstack *S)
{
S->base = (int*)malloc(STACK_INIT_SIZE * sizeof(int));
if (!S->base)
exit(OVERFLOW);
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return OK;
}
Status InitQueue(LinkQueue* Q)
{
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q->front)
exit(OVERFLOW);
Q->front->next = NULL;
return OK;
}
Status Push(Sqstack *S, int e)
{
if (S->top - S->base >= S->stacksize)
{
S->base = (int*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(int));
if (!S->base)
exit(OVERFLOW);
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = e;
return OK;
}
Status EnQueue(LinkQueue* Q, int e)
{
QueuePtr p=NULL;
p = (QueuePtr)malloc(sizeof(QNode));
if (!p)
exit(OVERFLOW);
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
Status StackEmpty(Sqstack S)
{
if (S.top == S.base)
return OK;
else
return ERROR;
}
Status QueueEmpty(LinkQueue Q)
{
if (Q.front == Q.rear)
return OK;
else
return ERROR;
}
Status Pop(Sqstack* S, int* e)
{
if (S->top == S->base)
return ERROR;
*e = *(--S->top);
return OK;
}
Status DeQueue(LinkQueue* Q, int *e)
{
QueuePtr p=NULL;
if (Q->front == Q->rear)
return ERROR;
p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
free(p);
return OK;
}
void AddEdge(ArcNode* p1, ArcNode* p2)
{
ArcNode* p = p1;
while (p->nextarc)
p = p->nextarc;
p->nextarc = p2;
}
void CreateGraph(ALGraph* G, int indegree[]) {
printf("请输入当前图的顶点数和弧数:\n");
scanf_s("%d %d", &G->vexnum, &G->arcnum);
printf("请输入顶点:\n");
for (int i = 0; i < G->vexnum; i++) {
scanf_s(" %c", &G->vertices[i].data);
G->vertices[i].firstarc = NULL;
}
for (int i = 0; i < G->arcnum; i++) {
int start, end;
while (1) {
printf("请输入第%d条弧所依附的顶点及其所指向的顶点的位置信息:\n", i + 1);
scanf_s("%d %d", &start, &end);
if (start >= 0 && start < G->vexnum && end >= 0 && end < G->vexnum) {
break;
}
else {
printf("输入的顶点位置无效,请重新输入!\n");
}
}
ArcNode* NewNode = (ArcNode*)malloc(sizeof(ArcNode));
if (!NewNode) {
printf("Memory allocation failed\n");
exit(OVERFLOW);
}
NewNode->adjvex = end;
NewNode->nextarc = NULL;
indegree[end]++;
if (G->vertices[start].firstarc == NULL) {
G->vertices[start].firstarc = NewNode;
}
else {
AddEdge(G->vertices[start].firstarc, NewNode);
}
}
}
Status LocateVex(MGraph G,VertexType v)
{
int i;
for (i = 0; i < G.vexnum; i++)
if (v == G.vexs[i])
return i;
return -1;
}
Status CreateDG(MGraph* G, int indegree[]) {
int i, j, x, y;
VertexType v1, v2;
printf("请输入顶点数和边数:\n");
scanf_s("%d %d", &G->vexnum, &G->arcnum);
for (i = 0; i < G->vexnum; i++)
for (j = 0; j < G->vexnum; j++)
G->arcs[i][j] = 0;
printf("请输入顶点:\n");
for (i = 0; i < G->vexnum; i++)
scanf_s(" %c", &G->vexs[i]);
for (i = 0; i < G->arcnum; i++) {
while (1) {
printf("请输入第%d条弧所依附的两个顶点:\n", i + 1);
scanf_s(" %c", &v1);
scanf_s(" %c", &v2);
x = LocateVex(*G, v1);
y = LocateVex(*G, v2);
if (x != -1 && y != -1) {
break;
}
else {
printf("输入的顶点无效,请重新输入!\n");
}
}
G->arcs[x][y] = 1;
indegree[y]++;
}
return OK;
}
Status TopologicalSort(ALGraph *G,int indegree[])//邻接链表存储,栈实现拓扑排序
{
Sqstack S;
ArcNode* p;
InitStack(&S);
int i,k;
for (i = 0; i < G->vexnum; i++)
if (!indegree[i])
Push(&S, i);
int count = 0;
while (!StackEmpty(S))
{
Pop(&S, &i);
printf("%c", G->vertices[i].data);
count++;
for (p = G->vertices[i].firstarc; p; p = p->nextarc)
{
k = p->adjvex;
if (!(--indegree[k]))
Push(&S, k);
}
}
if (count < G->vexnum)
{
printf("不符合拓扑排序条件,无法进行排序");
return ERROR;
}
else
return OK;
}
Status TopologicalSort2(ALGraph* G, int indegree[])
{
LinkQueue Q;
ArcNode* p;
InitQueue(&Q);
int i, k;
for (i = 0; i < G->vexnum; i++)
if (!indegree[i])
EnQueue(&Q, i);
int count = 0;
while (!QueueEmpty(Q))
{
DeQueue(&Q, &i);
printf("%c", G->vertices[i].data);
count++;
for (p = G->vertices[i].firstarc; p; p = p->nextarc)
{
k = p->adjvex;
if (!(--indegree[k]))
EnQueue(&Q, k);
}
}
if (count < G->vexnum)
{
printf("不符合拓扑排序条件,无法进行排序");
return ERROR;
}
else
return OK;
}
Status TopologicalSort3(MGraph* G, int indegree[])
{
Sqstack S;
ArcNode* p;
InitStack(&S);
int i, k;
for (i = 0; i < G->vexnum; i++)
if (!indegree[i])
Push(&S, i);
int count = 0;
while (!StackEmpty(S))
{
Pop(&S, &i);
printf("%c", G->vexs[i]);
count++;
for (int k = 0; k < G->vexnum; k++)
{
if (G->arcs[i][k])
{
if (!(--indegree[k]))
Push(&S, k);
}
}
}
if (count < G->vexnum)
{
printf("不符合拓扑排序条件,无法进行排序");
return ERROR;
}
else
return OK;
}
Status TopologicalSort4(MGraph* G,int indegree[])//邻接矩阵存储,队列实现拓扑排序
{
LinkQueue Q;
InitQueue(&Q);
int i, k;
for (i = 0; i < G->vexnum; i++)
if (!indegree[i])
EnQueue(&Q, i);
int count = 0;
while (!QueueEmpty(Q))
{
DeQueue(&Q, &i);
printf("%c", G->vexs[i]);
count++;
for (int k=0;kvexnum;k++)
{
if (G->arcs[i][k])
{
if (!(--indegree[k]))
EnQueue(&Q, k);
}
}
}
if (count < G->vexnum)
{
printf("不符合拓扑排序条件,无法进行排序");
return ERROR;
}
else
return OK;
}
int main() {
int indegree[MAX_VERTEX_NUM] = { 0 };
int fs, choice;
do {
printf("请选择有向图采用的存储结构:\n1.邻接链表 2.邻接矩阵 3.退出\n");
scanf_s("%d", &fs);
system("cls");
if (fs == 3) {
printf("程序已退出。\n");
break;
}
else if (fs == 1) {
ALGraph* G = (ALGraph*)malloc(sizeof(ALGraph));
CreateGraph(G, indegree);
printf("请选择实现拓扑排序的方式:\n1.栈 2.队列\n");
scanf_s("%d", &fs);
system("cls");
if (fs == 1) {
TopologicalSort(G, indegree);
}
else if (fs == 2) {
TopologicalSort2(G, indegree);
}
free(G);
}
else if (fs == 2) {
MGraph* G = (MGraph*)malloc(sizeof(MGraph));
CreateDG(G, indegree);
printf("请选择实现拓扑排序的方式:\n1.栈 2.队列\n");
scanf_s("%d", &fs);
system("cls");
if (fs == 1) {
TopologicalSort3(G, indegree);
}
else if (fs == 2) {
TopologicalSort4(G, indegree);
}
free(G);
}
else {
printf("无效的输入,请重新选择。\n");
continue;
}
printf("\n是否继续选择其他操作?(1.继续 2.退出)\n");
scanf_s("%d", &choice);
system("cls");
} while (choice == 1);
return 0;
}
用c#写的可视化界面
//Form1.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using YourProjectName.Models;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
private List vertices;
private List edges;
private List sortedVertices;
private Queue zeroIndegreeQueue;
private Dictionary indegree;
private const int ANIMATION_SPEED = 1000;
private bool useStack = true; // 默认使用栈
public Form1()
{
InitializeComponent();
vertices = new List();
edges = new List();
sortedVertices = new List();
zeroIndegreeQueue = new Queue();
indegree = new Dictionary();
SetupEventHandlers();
}
private void cmbAlgorithm_SelectedIndexChanged(object sender, EventArgs e)
{
useStack = cmbAlgorithm.SelectedItem.ToString().Contains("基于栈");
}
private void SetupEventHandlers()
{
btnCreate.Click += BtnCreate_Click;
btnSort.Click += BtnSort_Click;
btnNext.Click += BtnNext_Click;
btnReset.Click += BtnReset_Click;
drawPanel.Paint += DrawPanel_Paint;
}
private void BtnCreate_Click(object sender, EventArgs e)
{
try
{
if (cmbStorageType.SelectedItem.ToString() == "邻接矩阵")
{
CreateGraphUsingMatrix();
}
else if(cmbStorageType.SelectedItem.ToString() == "邻接链表")
{
CreateGraphUsingList();
}
else
{
CreateGraphFromInput();
}
LayoutGraph();
drawPanel.Invalidate();
btnSort.Enabled = true;
btnNext.Enabled = false;
UpdateStatus("图创建成功!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CreateGraphUsingMatrix()
{
int vertexCount = 6;
vertices.Clear();
edges.Clear();
sortedVertices.Clear();
zeroIndegreeQueue.Clear();
indegree.Clear();
// 初始化顶点
var vertexNames = new[] { 'A', 'B', 'C', 'D', 'E' ,'F'};
for (int i = 0; i < vertexCount; i++)
{
var vertex = new Vertex(vertexNames[i]);
vertices.Add(vertex);
indegree[vertex] = 0;
}
// 邻接矩阵
bool[,] adjacencyMatrix = new bool[vertexCount, vertexCount];
// 添加边
AddEdgeToMatrix(adjacencyMatrix, 'A', 'B');
AddEdgeToMatrix(adjacencyMatrix, 'A', 'D');
AddEdgeToMatrix(adjacencyMatrix, 'A', 'C');
AddEdgeToMatrix(adjacencyMatrix, 'E', 'C');
AddEdgeToMatrix(adjacencyMatrix, 'E', 'F');
AddEdgeToMatrix(adjacencyMatrix, 'C', 'F');
AddEdgeToMatrix(adjacencyMatrix, 'D', 'B');
AddEdgeToMatrix(adjacencyMatrix, 'D', 'F');
// 将邻接矩阵中的边转换为Edge对象
for (int i = 0; i < vertexCount; i++)
{
for (int j = 0; j < vertexCount; j++)
{
if (adjacencyMatrix[i, j])
{
edges.Add(new Edge(vertices[i], vertices[j]));
}
}
}
}
private void CreateGraphUsingList()
{
vertices.Clear();
edges.Clear();
sortedVertices.Clear();
zeroIndegreeQueue.Clear();
indegree.Clear();
// 初始化顶点
var vertexNames = new[] { 'A', 'B', 'C', 'D', 'E' };
foreach (var v in vertexNames)
{
var vertex = new Vertex(v);
vertices.Add(vertex);
indegree[vertex] = 0;
}
// 使用邻接链表添加边
AddEdgeToList('A', 'C');
AddEdgeToList('B', 'C');
AddEdgeToList('A', 'E');
AddEdgeToList('D', 'E');
AddEdgeToList('B', 'E');
AddEdgeToList('B', 'D');
}
private void AddEdgeToList(char fromValue, char toValue)
{
var from = vertices.Find(v => v.Value == fromValue);
var to = vertices.Find(v => v.Value == toValue);
if (from == null || to == null)
{
throw new Exception($"边 {fromValue}->{toValue} 包含不存在的顶点!");
}
from.Neighbors.Add(to);
edges.Add(new Edge(from, to)); // 创建并添加边
indegree[to]++;
}
private void AddEdgeToMatrix(bool[,] matrix, char fromValue, char toValue)
{
int fromIndex = vertices.FindIndex(v => v.Value == fromValue);
int toIndex = vertices.FindIndex(v => v.Value == toValue);
if (fromIndex == -1 || toIndex == -1)
{
throw new Exception($"边 {fromValue}->{toValue} 包含不存在的顶点!");
}
matrix[fromIndex, toIndex] = true;
indegree[vertices[toIndex]]++;
}
private void CreateGraphFromInput()
{
vertices.Clear();
edges.Clear();
sortedVertices.Clear();
zeroIndegreeQueue.Clear();
indegree.Clear();
var vertexInput = txtVertices.Text.Replace(" ", "").Split(',');
foreach (var v in vertexInput)
{
if (string.IsNullOrEmpty(v)) continue;
var vertex = new Vertex(v[0]);
vertices.Add(vertex);
indegree.Add(vertex, 0); // Initialize indegree to 0
}
var edgeInput = txtEdges.Text.Replace(" ", "").Split(',');
foreach (var e in edgeInput)
{
if (string.IsNullOrEmpty(e) || e.Length < 3) continue;
if (e[1] != '-' || e[2] != '>')
throw new Exception("边的格式错误,请使用 A->B 格式!");
var from = vertices.Find(v => v.Value == e[0]);
var to = vertices.Find(v => v.Value == e[3]);
if (from == null || to == null)
throw new Exception($"边 {e} 包含不存在的顶点!");
edges.Add(new Edge(from, to));
if (!indegree.ContainsKey(to))
indegree[to] = 0;
indegree[to]++;
from.Neighbors.Add(to);
}
}
private void LayoutGraph()
{
int radius = Math.Min(drawPanel.Width, drawPanel.Height) / 3;
Point center = new Point(drawPanel.Width / 2 - 100, drawPanel.Height / 2);
double startAngle = -Math.PI / 2;
for (int i = 0; i < vertices.Count; i++)
{
double angle = startAngle + (2 * Math.PI * i / vertices.Count);
int x = (int)(center.X + radius * Math.Cos(angle));
int y = (int)(center.Y + radius * Math.Sin(angle));
vertices[i].Location = new Point(x, y);
}
}
private void DrawQueueInfo(Graphics g)
{
int y = drawPanel.Height - 100; // 距离底部100像素的位置
int x = 10; // 距离左侧10像素的位置
using (var font = new Font("微软雅黑", 15))
using (var brush = new SolidBrush(Color.FromArgb(44, 62, 80)))
{
string queueInfo = useStack ? "栈中的元素: " : "队列中的元素: ";
foreach (var vertex in zeroIndegreeQueue)
{
queueInfo += vertex.Value + " ";
}
g.DrawString(queueInfo, font, brush, new Point(x, y));
}
}
private void DrawPanel_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// 绘制边
foreach (var edge in edges)
{
if (edge.Visible)
{
using (var pen = new Pen(edge.Color, 2))
{
DrawArrow(e.Graphics, edge.From.Location, edge.To.Location, pen);
}
}
}
// 绘制顶点
foreach (var vertex in vertices)
{
var rect = new Rectangle(
vertex.Location.X - 20,
vertex.Location.Y - 20,
40, 40);
using (var brush = new SolidBrush(vertex.Color))
{
e.Graphics.FillEllipse(brush, rect);
}
using (var brush = new SolidBrush(Color.White))
{
var format = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
e.Graphics.DrawString(
vertex.Value.ToString(),
new Font("Arial", 12, FontStyle.Bold),
brush,
vertex.Location,
format);
}
}
// 绘制已排序的顶点
foreach (var sortedVertex in sortedVertices)
{
var rect = new Rectangle(
sortedVertex.Location.X - 20,
sortedVertex.Location.Y - 20,
40, 40);
using (var brush = new SolidBrush(sortedVertex.Color))
{
e.Graphics.FillEllipse(brush, rect);
}
using (var brush = new SolidBrush(Color.White))
{
var format = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
e.Graphics.DrawString(
sortedVertex.Value.ToString(),
new Font("Arial", 12, FontStyle.Bold),
brush,
sortedVertex.Location,
format);
}
}
DrawQueueInfo(e.Graphics);
DrawInDegreeInfo(e.Graphics);
}
private void DrawArrow(Graphics g, Point start, Point end, Pen pen)
{
const float arrowSize = 15;
float angle = (float)Math.Atan2(end.Y - start.Y, end.X - start.X);
Point adjustedStart = new Point(
(int)(start.X + 22 * Math.Cos(angle)),
(int)(start.Y + 22 * Math.Sin(angle))
);
Point adjustedEnd = new Point(
(int)(end.X - 22 * Math.Cos(angle)),
(int)(end.Y - 22 * Math.Sin(angle))
);
g.DrawLine(pen, adjustedStart, adjustedEnd);
Point[] arrowHead = new Point[]
{
adjustedEnd,
new Point(
(int)(adjustedEnd.X - arrowSize * Math.Cos(angle - Math.PI / 6)),
(int)(adjustedEnd.Y - arrowSize * Math.Sin(angle - Math.PI / 6))
),
new Point(
(int)(adjustedEnd.X - arrowSize * Math.Cos(angle + Math.PI / 6)),
(int)(adjustedEnd.Y - arrowSize * Math.Sin(angle + Math.PI / 6))
)
};
g.FillPolygon(new SolidBrush(pen.Color), arrowHead);
}
private void DrawInDegreeInfo(Graphics g)
{
int y = 20;
int x = drawPanel.Width - 300;
using (var font = new Font("微软雅黑", 14))
using (var brush = new SolidBrush(Color.FromArgb(44, 62, 80)))
{
foreach (var vertex in vertices)
{
string info = $"顶点 {vertex.Value} 的入度: {indegree[vertex]}";
g.DrawString(info, font, brush, new Point(x, y));
y += 40;
}
}
}
private void BtnSort_Click(object sender, EventArgs e)
{
btnSort.Enabled = false;
btnNext.Enabled = true;
sortedVertices.Clear();
var zeroIndegreeVertices = vertices.Where(v => indegree[v] == 0).ToList();
if (useStack)
{
var stack = new Stack(zeroIndegreeVertices.OrderByDescending(v => v.Value));
zeroIndegreeQueue = new Queue(stack);
}
else
{
zeroIndegreeQueue = new Queue(zeroIndegreeVertices.OrderBy(v => v.Value));
}
foreach (var vertex in zeroIndegreeQueue)
{
vertex.Color = Color.Blue;
}
lblStatus.Text = "";
drawPanel.Invalidate();
}
private async void BtnNext_Click(object sender, EventArgs e)
{
if (zeroIndegreeQueue.Count == 0)
{
if (sortedVertices.Count < vertices.Count)
{
UpdateStatus("无法继续排序,图中存在环或未处理的顶点。");
}
else
{
UpdateStatus("拓扑排序完成!");
}
btnNext.Enabled = false;
return;
}
Vertex current;
if (useStack)
{
var stack = new Stack(zeroIndegreeQueue);
current = stack.Pop();
zeroIndegreeQueue = new Queue(stack);
}
else
{
current = zeroIndegreeQueue.Dequeue();
}
await AnimateVertexColor(current, Color.Green);
sortedVertices.Add(current);
foreach (var edge in edges)
{
if (edge.From == current && edge.Visible)
{
edge.Visible = false;
if (--indegree[edge.To] == 0)
{
if (useStack)
{
var stack = new Stack(zeroIndegreeQueue);
stack.Push(edge.To);
zeroIndegreeQueue = new Queue(stack);
}
else
{
zeroIndegreeQueue.Enqueue(edge.To);
}
edge.To.Color = Color.Blue;
}
}
}
UpdateSortingResult();
LayoutSortedVertices();
drawPanel.Invalidate(); // 触发重绘
}
private void LayoutSortedVertices()
{
// 定义最左边的X坐标
int x = 20;
// 每个顶点的直径
int diameter = 40;
// 顶点之间的垂直间距
int gap = 20;
for (int i = 0; i < sortedVertices.Count; i++)
{
// 计算Y坐标,每个顶点之间有一定的间隔
int y = 20 + i * (diameter + gap);
// 设置顶点的新位置
sortedVertices[i].Location = new Point(x, y);
}
}
private async Task AnimateVertexColor(Vertex vertex, Color color)
{
vertex.Color = color;
drawPanel.Invalidate();
await Task.Delay(ANIMATION_SPEED);
}
private async Task AnimateEdgeRemoval(Vertex from, Vertex to)
{
var edge = edges.Find(e => e.From == from && e.To == to);
if (edge != null)
{
edge.Visible = false;
drawPanel.Invalidate();
await Task.Delay(ANIMATION_SPEED / 2);
}
}
private void UpdateStatus(string message)
{
lblStatus.Text = message;
lblStatus.ForeColor = message.Contains("错误") ?
Color.FromArgb(192, 57, 43) : Color.FromArgb(39, 174, 96);
}
private void UpdateSortingResult()
{
string result = "拓扑排序结果:";
for (int i = 0; i < sortedVertices.Count; i++)
{
result += sortedVertices[i].Value;
if (i < sortedVertices.Count - 1)
{
result += " -> ";
}
}
lblStatus.Text = result;
lblStatus.ForeColor = Color.FromArgb(39, 174, 96);
}
private void BtnReset_Click(object sender, EventArgs e)
{
vertices.Clear();
edges.Clear();
sortedVertices.Clear();
zeroIndegreeQueue.Clear();
indegree.Clear();
txtVertices.Clear();
txtEdges.Clear();
btnSort.Enabled = false;
btnNext.Enabled = false;
UpdateStatus("");
drawPanel.Invalidate();
}
}
}
//Form1.Designer.cs
namespace WinFormsApp1
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
private Panel drawPanel;
private TextBox txtVertices;
private TextBox txtEdges;
private Button btnCreate;
private Button btnSort;
private Button btnNext;
private Button btnReset;
private ComboBox cmbAlgorithm;
private ComboBox cmbStorageType;
private Label lblStatus;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(2600, 1800); // 调整窗口大小
this.Text = "拓扑排序可视化";
this.BackColor = Color.FromArgb(236, 240, 241);
this.StartPosition = FormStartPosition.CenterScreen;
// 绘图面板
drawPanel = new Panel
{
Location = new Point(80, 200),
Size = new Size(2400, 1200),
BackColor = Color.White,
BorderStyle = BorderStyle.FixedSingle
};
// 顶点输入框
txtVertices = new TextBox
{
Location = new Point(480, 40),
Size = new Size(550, 60),
Font = new Font("微软雅黑", 10F),
PlaceholderText = "输入顶点 (例如: A,B,C)"
};
// 边输入框
txtEdges = new TextBox
{
Location = new Point(480, 120),
Size = new Size(550, 60),
Font = new Font("微软雅黑", 10F),
PlaceholderText = "输入边 (例如: A->B,B->C)"
};
// 算法选择下拉框
cmbAlgorithm = new ComboBox
{
Location = new Point(80, 120),
Size = new Size(350, 60),
DropDownStyle = ComboBoxStyle.DropDownList,
Font = new Font("微软雅黑", 10F)
};
cmbAlgorithm.Items.AddRange(new object[] {
"基于栈的拓扑排序",
"基于队列的拓扑排序"
});
cmbAlgorithm.SelectedIndex = 0;
// 存储方式选择下拉框
cmbStorageType = new ComboBox
{
Location = new Point(80, 40),
Size = new Size(350, 60),
DropDownStyle = ComboBoxStyle.DropDownList,
Font = new Font("微软雅黑", 10F)
};
cmbStorageType.Items.AddRange(new object[] {
"邻接矩阵",
"邻接链表",
"手动输入"
});
cmbStorageType.SelectedIndex = 0;
// 按钮
btnCreate = CreateStyledButton("创建图", new Point(1200, 40));
btnSort = CreateStyledButton("开始排序", new Point(1550, 40));
btnNext = CreateStyledButton("下一步", new Point(1900, 40));
btnReset = CreateStyledButton("重置", new Point(2250, 40));
btnSort.Enabled = false;
btnNext.Enabled = false;
// 状态标签
lblStatus = new Label
{
Location = new Point(80, 1440),
Size = new System.Drawing.Size(2200, 60),
Font = new Font("微软雅黑", 14F, FontStyle.Bold),
ForeColor = Color.FromArgb(52, 73, 94)
};
// 添加控件
Controls.AddRange(new Control[] {
drawPanel, txtVertices, txtEdges, cmbAlgorithm, cmbStorageType,
btnCreate, btnSort, btnNext, btnReset, lblStatus
});
cmbAlgorithm.SelectedIndexChanged += cmbAlgorithm_SelectedIndexChanged;
}
private Button CreateStyledButton(string text, Point location)
{
var btn = new Button
{
Text = text,
Location = location,
Size = new Size(200, 80),
Font = new Font("微软雅黑", 10F),
FlatStyle = FlatStyle.Flat,
BackColor = Color.FromArgb(52, 152, 219), // 初始颜色
ForeColor = Color.White,
Cursor = Cursors.Hand
};
// 设置鼠标悬浮时的事件处理
btn.MouseEnter += (sender, e) =>
{
// 鼠标悬浮时改变背景颜色为绿色
((Button)sender).BackColor = Color.Green;
};
// 设置鼠标离开时的事件处理
btn.MouseLeave += (sender, e) =>
{
// 鼠标离开时恢复初始背景颜色
((Button)sender).BackColor = Color.FromArgb(52, 152, 219);
};
btn.FlatAppearance.BorderSize = 0; // 如果您不想要边框,可以设置边框大小为0
return btn;
}
}
}
//Edge.cs
using System.Drawing;
namespace YourProjectName.Models
{
public class Edge
{
public Vertex From { get; set; }
public Vertex To { get; set; }
public bool Visible { get; set; }
public Color Color { get; set; }
public Edge(Vertex from, Vertex to)
{
From = from;
To = to;
Visible = true;
Color = Color.FromArgb(44, 62, 80);
}
}
}
//Vertex.cs
using System.Drawing;
namespace YourProjectName.Models
{
public class Vertex
{
public char Value { get; set; }
public Point Location { get; set; }
public List Neighbors { get; set; }
public int InDegree { get; set; }
public Color Color { get; set; }
public Vertex(char value)
{
Value = value;
Neighbors = new List();
InDegree = 0;
Color = Color.Black; // 初始颜色
}
}
}
//Program.cs
using System;
using System.Windows.Forms;
namespace WinFormsApp1
{
internal static class Program
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
}