首页 / 资讯中心 / 文章详情

C语言数据结构与算法实战:结构体数组、链表操作与回文检测

C语言数据结构与算法实战:结构体数组、链表操作与回文检测 ★ FEATURED ARTICLE
1. 结构体数组寻找最高分学生在处理学生成绩数据时结构体数组是最常用的数据结构之一。假设我们有一个包含学生姓名和成绩的结构体数组要找到成绩最高的学生可以这样实现#include stdio.h #include string.h #define MAX_STUDENTS 100 typedef struct { char name[50]; int score; } Student; Student findTopStudent(Student students[], int count) { Student top students[0]; for (int i 1; i count; i) { if (students[i].score top.score) { top students[i]; } } return top; } int main() { Student class[MAX_STUDENTS] { {张三, 85}, {李四, 92}, {王五, 78}, // 可以继续添加更多学生 }; int studentCount 3; // 当前学生数量 Student top findTopStudent(class, studentCount); printf(最高分学生: %s, 分数: %d\n, top.name, top.score); return 0; }注意在实际应用中应该考虑学生分数相同的情况可能需要返回所有最高分学生或处理并列情况。2. 链表操作求两个字符串链表的差集链表差集操作是指找出在第一个链表中存在但在第二个链表中不存在的元素。对于字符串链表我们需要特别注意字符串的比较方式#include stdio.h #include stdlib.h #include string.h #include stdbool.h typedef struct StringNode { char *value; struct StringNode *next; } StringNode; // 检查字符串是否在链表中 bool contains(StringNode *head, const char *str) { while (head ! NULL) { if (strcmp(head-value, str) 0) { return true; } head head-next; } return false; } // 求两个链表的差集 StringNode *difference(StringNode *list1, StringNode *list2) { StringNode *result NULL; StringNode **tail result; while (list1 ! NULL) { if (!contains(list2, list1-value)) { *tail (StringNode *)malloc(sizeof(StringNode)); (*tail)-value strdup(list1-value); (*tail)-next NULL; tail ((*tail)-next); } list1 list1-next; } return result; } // 辅助函数打印链表 void printList(StringNode *head) { while (head ! NULL) { printf(%s , head-value); head head-next; } printf(\n); } // 示例用法 int main() { // 创建链表1: a - b - c - d StringNode *list1 NULL; StringNode **tail1 list1; const char *values1[] {a, b, c, d, NULL}; for (int i 0; values1[i] ! NULL; i) { *tail1 (StringNode *)malloc(sizeof(StringNode)); (*tail1)-value strdup(values1[i]); (*tail1)-next NULL; tail1 ((*tail1)-next); } // 创建链表2: b - d - e StringNode *list2 NULL; StringNode **tail2 list2; const char *values2[] {b, d, e, NULL}; for (int i 0; values2[i] ! NULL; i) { *tail2 (StringNode *)malloc(sizeof(StringNode)); (*tail2)-value strdup(values2[i]); (*tail2)-next NULL; tail2 ((*tail2)-next); } printf(链表1: ); printList(list1); printf(链表2: ); printList(list2); StringNode *diff difference(list1, list2); printf(差集(链表1 - 链表2): ); printList(diff); // 释放内存(实际应用中不要忘记) // ... return 0; }提示在实际应用中应该考虑内存管理问题确保分配的内存最终被正确释放。3. 质数求和计算一定范围内所有质数的和是一个常见的编程练习。以下是高效的实现方法#include stdio.h #include stdbool.h #include math.h // 检查一个数是否是质数 bool isPrime(int num) { if (num 1) return false; if (num 2) return true; if (num % 2 0) return false; int sqrtNum sqrt(num) 1; for (int i 3; i sqrtNum; i 2) { if (num % i 0) { return false; } } return true; } // 计算范围内所有质数的和 long sumOfPrimes(int start, int end) { long sum 0; for (int i start; i end; i) { if (isPrime(i)) { sum i; } } return sum; } int main() { int start 1; int end 100; long sum sumOfPrimes(start, end); printf(%d到%d之间所有质数的和为: %ld\n, start, end, sum); return 0; }优化建议对于大范围计算可以使用筛法如埃拉托斯特尼筛法提高效率可以缓存已计算的质数避免重复计算对于非常大的范围可以考虑并行计算4. 最长回文子串长度寻找字符串中的最长回文子串是一个经典的算法问题。以下是动态规划解法#include stdio.h #include string.h #include stdbool.h int longestPalindromeSubstr(const char *s) { int n strlen(s); if (n 0) return 0; // 创建动态规划表 bool dp[n][n]; memset(dp, 0, sizeof(dp)); int maxLength 1; // 所有单个字符都是回文 // 单个字符都是回文 for (int i 0; i n; i) { dp[i][i] true; } // 检查长度为2的子串 for (int i 0; i n - 1; i) { if (s[i] s[i 1]) { dp[i][i 1] true; maxLength 2; } } // 检查长度大于2的子串 for (int len 3; len n; len) { for (int i 0; i n - len; i) { int j i len - 1; // 子串结束索引 if (s[i] s[j] dp[i 1][j - 1]) { dp[i][j] true; if (len maxLength) { maxLength len; } } } } return maxLength; } int main() { const char *str babad; int length longestPalindromeSubstr(str); printf(字符串 %s 的最长回文子串长度为: %d\n, str, length); return 0; }其他解法中心扩展法从每个字符或每两个字符之间向两边扩展寻找最长回文Manacher算法线性时间复杂度解法适合处理超长字符串实际应用中的优化技巧对于非常长的字符串可以先检查整个字符串是否是回文可以记录最长回文的起始位置而不仅仅是长度考虑使用更高效的内存访问模式优化动态规划表的访问
阅读完成 · 觉得有帮助?
咨询建站