1. 程式人生 > >《程序設計基礎》實驗題目2 c文件讀取(反序列化?) 鏈表排序

《程序設計基礎》實驗題目2 c文件讀取(反序列化?) 鏈表排序

max malloc 哨兵 scan 遞歸 初始化 直接 元素 oid

題目:

  每個學生的信息卡片包括學號、姓名和成績三項。定義存儲學生信息的單向鏈表的結點類型;編寫函 數,由文件依次讀入 n(n≥0)個學生的信息,創建一個用於管理學生信息的單向鏈表;編寫函數,對 該鏈表進行整理,保證該單向鏈表的結點順序滿足學號從小到大的順序。

算法的設計與分析:

  1. 定義學生類型結構體(含有分量id,name,score),定義鏈表節點結構體(含有分量student結構體stu和指向下一個節點的指針next)
  2. 從文件讀取,采用fopen方法返回FILE指針,用fscanf方法讀取數據並創建節點組成鏈表
    1. 還可以使用freopen的方法,直接scanf即可
    2. 或者用我一開始的土方法,用fgets函數讀取一行,用stroke分割該行字符串,將字符串轉化成int,創建結構體。比上面的方法復雜多了。
  3. 按學號排序,采用插入排序的方法,插入排序,以sorted(初始為第一個元素)為邊界,將sorted後的一個節點插在前面已經排好的鏈表中,直到sorted後沒有節點

註意:

  1. char* 結構體*等指針要用必須分配空間
    1. 分配空間通常使用malloc函數,A* a=(*A)malloc(sizeof(A))
  2. malloc申請的空間要free掉,free(a)
  3. 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\n", 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("\n sorted:\n"); 102 //按學號排序後打印學生數據 103 sortListByStuId(students); 104 showStuInfor(students->next); 105 freeNodes(students); 106 } 107 108 int main() { 109 test(); 110 }

The end

《程序設計基礎》實驗題目2 c文件讀取(反序列化?) 鏈表排序