C语言链表程序集成绘图库:将终端打印转为图形展示
为C语言链表程序集成图形化展示功能
选择合适的绘图库
推荐用SDL2,跨平台(Windows/Linux/macOS),API简单直接,适合快速实现简单的图形界面和元素绘制,不需要复杂的UI框架。
集成步骤与代码示例
假设你的链表节点结构如下(可根据实际结构调整):
typedef struct Node { int vals[3]; // 对应节点的三元组值,比如[1:3:4] struct Node *next; } Node;
1. 初始化SDL2环境
先完成SDL视频子系统、窗口、渲染器以及字体模块的初始化:
#include <SDL2/SDL.h> #include <SDL2/SDL_ttf.h> // 用于绘制文本,需链接SDL_ttf库 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 400 #define NODE_WIDTH 100 #define NODE_HEIGHT 60 #define PADDING 20 SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; TTF_Font *font = NULL; // 初始化SDL及字体 int init_sdl() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "SDL初始化失败: %s\n", SDL_GetError()); return -1; } if (TTF_Init() != 0) { fprintf(stderr, "SDL_ttf初始化失败: %s\n", TTF_GetError()); SDL_Quit(); return -1; } window = SDL_CreateWindow("链表节点图形展示", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, 0); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); // 替换为你系统中存在的字体路径,比如Windows下的C:/Windows/Fonts/arial.ttf font = TTF_OpenFont("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16); if (!window || !renderer || !font) { fprintf(stderr, "创建窗口/渲染器/字体失败: %s\n", SDL_GetError()); cleanup(); return -1; } return 0; } // 清理SDL资源 void cleanup() { if (font) TTF_CloseFont(font); if (renderer) SDL_DestroyRenderer(renderer); if (window) SDL_DestroyWindow(window); TTF_Quit(); SDL_Quit(); }
2. 编写图形绘制函数
实现单个节点绘制、文本绘制以及节点间箭头连接的功能:
// 绘制文本辅助函数 void draw_text(int x, int y, const char *text, SDL_Color color) { SDL_Surface *surface = TTF_RenderText_Solid(font, text, color); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_Rect dest = {x, y, surface->w, surface->h}; SDL_RenderCopy(renderer, texture, NULL, &dest); SDL_FreeSurface(surface); SDL_DestroyTexture(texture); } // 绘制单个链表节点 void draw_node(Node *node, int x, int y) { // 绘制节点矩形框 SDL_Rect node_rect = {x, y, NODE_WIDTH, NODE_HEIGHT}; SDL_SetRenderDrawColor(renderer, 0, 128, 255, 255); SDL_RenderDrawRect(renderer, &node_rect); SDL_SetRenderDrawColor(renderer, 200, 230, 255, 255); SDL_RenderFillRect(renderer, &node_rect); // 绘制节点的三元组值(居中显示) char val_str[32]; sprintf(val_str, "[%d:%d:%d]", node->vals[0], node->vals[1], node->vals[2]); SDL_Color text_color = {0, 0, 0, 255}; int text_w, text_h; TTF_SizeText(font, val_str, &text_w, &text_h); draw_text(x + (NODE_WIDTH - text_w)/2, y + (NODE_HEIGHT - text_h)/2, val_str, text_color); } // 绘制节点间的连接箭头 void draw_arrow(int start_x, int start_y, int end_x, int end_y) { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // 绘制箭头主线 SDL_RenderDrawLine(renderer, start_x + NODE_WIDTH, start_y + NODE_HEIGHT/2, end_x - PADDING, start_y + NODE_HEIGHT/2); // 绘制箭头头部 int arrow_size = 8; SDL_RenderDrawLine(renderer, end_x - PADDING, start_y + NODE_HEIGHT/2, end_x - PADDING - arrow_size, start_y + NODE_HEIGHT/2 - arrow_size); SDL_RenderDrawLine(renderer, end_x - PADDING, start_y + NODE_HEIGHT/2, end_x - PADDING - arrow_size, start_y + NODE_HEIGHT/2 + arrow_size); }
3. 替换原打印循环为图形展示循环
把原来的终端打印逻辑,替换为遍历链表并绘制图形的循环:
void draw_linked_list(Node *head) { if (!head) return; SDL_Event e; int running = 1; const int y_pos = (WINDOW_HEIGHT - NODE_HEIGHT)/2; // 节点垂直居中 while (running) { // 处理窗口事件(比如关闭窗口) while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { running = 0; } } // 清空画布 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); // 遍历链表绘制所有节点和连接箭头 Node *current = head; int current_x = PADDING; while (current != NULL) { draw_node(current, current_x, y_pos); if (current->next != NULL) { draw_arrow(current_x, y_pos, current_x + NODE_WIDTH + PADDING, y_pos); } current_x += NODE_WIDTH + PADDING * 2; current = current->next; } // 更新显示 SDL_RenderPresent(renderer); } }
4. 编译与运行
Linux下编译命令(需提前安装SDL2和SDL2_ttf开发包):
gcc your_program.c -o linked_list_graph -lSDL2 -lSDL2_ttf
Windows下需配置SDL的头文件和库路径,使用MinGW等工具链时编译参数类似。
注意事项
- 字体路径:
TTF_OpenFont中的路径必须是你系统中存在的字体文件路径,否则文本无法显示。 - 节点数量适配:如果链表节点过多导致窗口宽度不足,可增大
WINDOW_WIDTH,或添加鼠标滚动偏移的逻辑。 - 资源清理:程序退出前务必调用
cleanup()释放SDL资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者aghozzo
相关产品推荐
相关产品推荐

