《程序设计基础》实验题目2 c文件读取(反序列化?) 链表排序
Posted maxzheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《程序设计基础》实验题目2 c文件读取(反序列化?) 链表排序相关的知识,希望对你有一定的参考价值。
题目:
每个学生的信息卡片包括学号、姓名和成绩三项。定义存储学生信息的单向链表的结点类型;编写函 数,由文件依次读入 n(n≥0)个学生的信息,创建一个用于管理学生信息的单向链表;编写函数,对 该链表进行整理,保证该单向链表的结点顺序满足学号从小到大的顺序。
算法的设计与分析:
- 定义学生类型结构体(含有分量id,name,score),定义链表节点结构体(含有分量student结构体stu和指向下一个节点的指针next)
- 从文件读取,采用fopen方法返回FILE指针,用fscanf方法读取数据并创建节点组成链表
- 还可以使用freopen的方法,直接scanf即可
- 或者用我一开始的土方法,用fgets函数读取一行,用stroke分割该行字符串,将字符串转化成int,创建结构体。比上面的方法复杂多了。
- 按学号排序,采用插入排序的方法,插入排序,以sorted(初始为第一个元素)为边界,将sorted后的一个节点插在前面已经排好的链表中,直到sorted后没有节点
注意:
- char* 结构体*等指针要用必须分配空间
- 分配空间通常使用malloc函数,A* a=(*A)malloc(sizeof(A))
- malloc申请的空间要free掉,free(a)
- malloc和free这一对与new和delete这一对非常像,c++里动态分配空间用new,c里要用malloc
源代码(talk is cheap,show me the code)(屁话少说,放码过来)
1 #include <stdio.h> 2 #include<malloc.h> 3 #define NAME_MAX 20 //名字的最长长度 4 5 typedef struct my_student { 6 int id; 7 char* name; 8 int score; 9 } student; 10 typedef struct my_list_node { 11 student stu; 12 struct my_list_node *next; 13 } Node; 14 15 Node* getStuFromFile(char *path) { 16 //从文件中读取学生数据创建单链表并返回头指针 17 FILE *stu_file; 18 stu_file = fopen(path, "r"); 19 if (stu_file == NULL) {//如果路径不正确 20 printf("file path error!"); 21 return 0; 22 } 23 //循环从文件中读取数据创建节点 24 Node* head = (Node*)malloc(sizeof(Node));//哨兵节点 25 Node* current_node = head;//用于循环赋值时表示当前节点 26 while (!feof(stu_file)) { 27 Node* temp = (Node*)malloc(sizeof(Node)); 28 //id ,name,score分别表示临时节点的student的id等 29 int* id =&( temp->stu.id); 30 temp->stu.name = (char*)malloc(sizeof(char)*NAME_MAX); 31 char* name = temp->stu.name; 32 int* score = &(temp->stu.score); 33 //从文件中读取临时节点的各个数据并赋值 34 fscanf(stu_file, "%d %s %d", id, name, score); 35 //将临时节点设为当前节点的子节点 36 current_node->next = temp; 37 current_node = current_node->next; 38 } 39 current_node->next = 0; 40 fclose(stu_file); 41 return head; 42 } 43 void showStuInfor(Node* node) { 44 //递归打印每个学生的信息 45 if (node != 0) { 46 printf("%d %s %d ", node->stu.id, node->stu.name, node->stu.score); 47 if (node->next != 0) { 48 //递归 49 showStuInfor(node->next); 50 } 51 } 52 } 53 54 void insertNode(Node* preL, Node* preR) { 55 //在preL节点后插入preR后的节点 56 Node* insert= preR->next; 57 preR->next = preR->next->next; 58 insert->next = preL->next; 59 preL->next = insert; 60 } 61 void sortListByStuId(Node *head) { 62 //插入排序,以sorted为边界,将sorted后的一个节点插在前面已经排好的链表中,直到sorted后没有节点 63 64 //初始化sorted有一个节点,算是已经排好序 65 Node* sorted = head->next; 66 //将sorted后的一个节点插到前面 67 while (sorted->next != 0) { 68 Node* insert = sorted->next; 69 Node* loc = head; 70 //从head开始遍历该插入到什么地方 71 while (insert->stu.id > loc->next->stu.id) { 72 loc = loc->next; 73 } 74 //如果loc与sorted不相等执行插入,如果相等说明要插入的元素比sorted之前的都大,直接让sorted后移即可 75 if (loc != sorted) { 76 insertNode(loc, sorted); 77 } 78 else { 79 sorted = sorted->next; 80 } 81 } 82 } 83 void freeNodes(Node* head) { 84 //递归释放malloc申请的空间 85 if (head != 0) { 86 if (head->next != 0) { 87 //释放name占用的空间 88 free(head->next->stu.name); 89 //递归释放 90 freeNodes(head->next); 91 } 92 free(head); 93 } 94 } 95 void test() { 96 //测试函数 97 //从文件中读取学生数据并打印 98 char path[] = "D:\student.txt"; 99 Node* students = getStuFromFile(path); 100 showStuInfor(students->next); 101 printf(" sorted: "); 102 //按学号排序后打印学生数据 103 sortListByStuId(students); 104 showStuInfor(students->next); 105 freeNodes(students); 106 } 107 108 int main() { 109 test(); 110 }
The end
以上是关于《程序设计基础》实验题目2 c文件读取(反序列化?) 链表排序的主要内容,如果未能解决你的问题,请参考以下文章