據(jù)結(jié)構(gòu)教案實(shí)戰(zhàn):從鏈表到排序的C語(yǔ)言教學(xué)設(shè)計(jì)與避坑指南)
簡(jiǎn)介這份數(shù)據(jù)結(jié)構(gòu)教案面向高校計(jì)算機(jī)及相關(guān)專業(yè)學(xué)生與授課教師圍繞數(shù)據(jù)結(jié)構(gòu)課程的基礎(chǔ)概念與教學(xué)框架展開適合作為課堂講義、復(fù)習(xí)提綱或備課參考。壓縮包內(nèi)共1個(gè)doc文檔約522KB內(nèi)容以章節(jié)化教案形式組織涵蓋緒論、數(shù)據(jù)類型、抽象數(shù)據(jù)類型、算法設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)五大模塊并配有教學(xué)目的、重點(diǎn)難點(diǎn)、課時(shí)分配與作業(yè)安排。教案從數(shù)據(jù)元素、數(shù)據(jù)對(duì)象、邏輯結(jié)構(gòu)四類關(guān)系講到抽象數(shù)據(jù)類型的三元組表示再到類C語(yǔ)言描述與算法分析脈絡(luò)清晰。已有420人學(xué)習(xí)下載可幫助讀者快速梳理數(shù)據(jù)結(jié)構(gòu)核心術(shù)語(yǔ)、理解四種結(jié)構(gòu)關(guān)系并借助課時(shí)授課計(jì)劃把握教學(xué)節(jié)奏為后續(xù)編程與算法學(xué)習(xí)打下基礎(chǔ)。1. 數(shù)據(jù)結(jié)構(gòu)教案從“能跑”到“能講清楚”的那道坎帶過(guò)幾屆學(xué)生之后我越來(lái)越確信一件事數(shù)據(jù)結(jié)構(gòu)教案寫得好不好不取決于你把嚴(yán)蔚敏那本教材的目錄抄得多整齊而取決于你能不能讓學(xué)生在兩節(jié)課內(nèi)親手把鏈表反轉(zhuǎn)跑通、把冒泡排序的比較次數(shù)數(shù)清楚。熱搜里“數(shù)據(jù)結(jié)構(gòu) 王道408”“408數(shù)據(jù)結(jié)構(gòu)代碼必背”“數(shù)據(jù)結(jié)構(gòu)期末復(fù)習(xí)”這些詞反復(fù)出現(xiàn)說(shuō)明大部分人的真實(shí)訴求不是聽(tīng)懂概念而是能寫出來(lái)、能過(guò)考試、能在實(shí)驗(yàn)報(bào)告里交差。這份教案面向三類人剛接手?jǐn)?shù)據(jù)結(jié)構(gòu)課的年輕教師、需要給同學(xué)講題的助教、以及自學(xué) C 語(yǔ)言想補(bǔ)數(shù)據(jù)結(jié)構(gòu)這一環(huán)的在校生。它不講“什么是線性表”這種翻開書就有的話而是把每一節(jié)課拆成“先講什么、再演示什么、學(xué)生動(dòng)手寫什么、卡在哪里、怎么驗(yàn)收”五個(gè)動(dòng)作。C 語(yǔ)言是這門課的默認(rèn)載體因?yàn)橹羔?、結(jié)構(gòu)體、內(nèi)存布局這些東西只有用 C 寫一遍學(xué)生才會(huì)真正理解“鏈”和“表”的區(qū)別而不是停留在畫方框箭頭的層面。2. 教案骨架怎么搭課時(shí)、代碼量與學(xué)生基礎(chǔ)的對(duì)齊2.1 先定三個(gè)約束再排章節(jié)順序?qū)懡贪缸钊菀追嚨牡胤绞且簧蟻?lái)就按教材目錄排章節(jié)。教材是給“已經(jīng)會(huì)的人”復(fù)習(xí)用的教案是給“還不會(huì)的人”鋪路的兩者順序經(jīng)常沖突。我一般先定三個(gè)約束總課時(shí)比如 48 學(xué)時(shí)、學(xué)生 C 語(yǔ)言水平是否已經(jīng)能獨(dú)立寫結(jié)構(gòu)體和指針、考核方式筆試為主還是實(shí)驗(yàn)報(bào)告為主。這三個(gè)約束定下來(lái)章節(jié)順序基本就鎖死了。如果學(xué)生 C 語(yǔ)言只學(xué)到數(shù)組和函數(shù)指針還半懂不懂那鏈表這一章必須往后放先補(bǔ)一節(jié)課的“指針與結(jié)構(gòu)體回顧”。熱搜里“c語(yǔ)言指針”“c語(yǔ)言結(jié)構(gòu)體”常年高居不下恰恰說(shuō)明這是卡住大多數(shù)人的第一道坎。我的做法是第一節(jié)課不講數(shù)據(jù)結(jié)構(gòu)只講“如何用 C 描述一個(gè)節(jié)點(diǎn)”把struct和malloc講透再進(jìn)入線性表。約束項(xiàng)常見(jiàn)取值對(duì)教案的影響總課時(shí)32 / 48 / 64決定能否安排獨(dú)立實(shí)驗(yàn)課C 語(yǔ)言基礎(chǔ)只會(huì)數(shù)組 / 會(huì)指針 / 會(huì)文件操作決定是否補(bǔ)前置課考核方式筆試 / 實(shí)驗(yàn)報(bào)告 / 上機(jī)決定代碼演示的深度2.2 每節(jié)課的教案模板五個(gè)動(dòng)作我用的模板固定五個(gè)動(dòng)作寫教案時(shí)逐條填缺一條這節(jié)課就不完整引入場(chǎng)景用一個(gè)具體問(wèn)題開場(chǎng)比如“如何在 100 萬(wàn)條記錄里快速查一個(gè)學(xué)號(hào)”。概念最小化只講解決這個(gè)問(wèn)題必需的概念不展開?,F(xiàn)場(chǎng)寫代碼教師在投影上從空文件開始敲學(xué)生跟著敲。故意制造錯(cuò)誤比如鏈表刪除時(shí)忘記free讓學(xué)生看到內(nèi)存泄漏的后果。驗(yàn)收標(biāo)準(zhǔn)給出一個(gè)可運(yùn)行的測(cè)試用例學(xué)生跑通才算過(guò)。這個(gè)模板的好處是教案不再是“知識(shí)點(diǎn)羅列”而是一條可執(zhí)行的時(shí)間線。下面是一個(gè)鏈表插入節(jié)點(diǎn)的最小演示代碼我通常在第 3 個(gè)動(dòng)作里用#include stdio.h #include stdlib.h typedef struct Node { int data; struct Node *next; } Node; /* 在鏈表頭部插入新節(jié)點(diǎn)返回新的頭指針 */ Node* insert_head(Node *head, int value) { Node *new_node (Node*)malloc(sizeof(Node)); /* 分配節(jié)點(diǎn)內(nèi)存 */ if (new_node NULL) { return head; /* 分配失敗保持原鏈表不變 */ } new_node-data value; new_node-next head; /* 新節(jié)點(diǎn)指向原來(lái)的頭 */ return new_node; /* 新節(jié)點(diǎn)成為新的頭 */ } int main(void) { Node *head NULL; head insert_head(head, 10); head insert_head(head, 20); head insert_head(head, 30); for (Node *p head; p ! NULL; p p-next) { printf(%d , p-data); } return 0; }這段代碼的關(guān)鍵參數(shù)只有兩個(gè)head和value。head是當(dāng)前鏈表的頭指針允許為NULL表示空鏈表value是要插入的整數(shù)。邏輯說(shuō)明先malloc一個(gè)新節(jié)點(diǎn)把數(shù)據(jù)寫進(jìn)去再讓新節(jié)點(diǎn)的next指向原來(lái)的head最后返回新節(jié)點(diǎn)作為新的頭。學(xué)生最容易錯(cuò)的是忘記判斷malloc返回值或者把new_node-next head寫成head-next new_node后者在空鏈表上直接崩潰。教案里我會(huì)把這兩個(gè)錯(cuò)誤各演示一遍讓學(xué)生看到段錯(cuò)誤和內(nèi)存泄漏的實(shí)際表現(xiàn)。2.3 實(shí)驗(yàn)報(bào)告怎么設(shè)計(jì)才不流于形式熱搜里“數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)報(bào)告”是個(gè)高頻詞說(shuō)明學(xué)生真正頭疼的是報(bào)告怎么寫。我的教案里實(shí)驗(yàn)報(bào)告只要求三部分測(cè)試用例、運(yùn)行結(jié)果、異常分析。不要求抄代碼不要求畫流程圖。測(cè)試用例必須包含至少一個(gè)邊界情況比如空鏈表、單節(jié)點(diǎn)鏈表、刪除頭節(jié)點(diǎn)。運(yùn)行結(jié)果要求截圖或粘貼終端輸出。異常分析要求寫清楚“我遇到了什么錯(cuò)誤怎么定位的”。這樣設(shè)計(jì)的好處是學(xué)生沒(méi)法從網(wǎng)上抄一份報(bào)告交差因?yàn)楫惓7治鍪莻€(gè)人化的。我批改時(shí)只看異常分析那一段寫得具體就給高分。常見(jiàn)的好異常分析比如“刪除節(jié)點(diǎn)后程序輸出正常但用valgrind檢查發(fā)現(xiàn) 4 字節(jié)內(nèi)存泄漏原因是忘記free被刪節(jié)點(diǎn)。”這種報(bào)告才說(shuō)明學(xué)生真的動(dòng)手了。3. 核心章節(jié)的講法線性表、棧隊(duì)列、樹、排序怎么落地3.1 線性表先講數(shù)組的局限再引出鏈表線性表這一章我從不先講定義。開場(chǎng)直接給一個(gè)場(chǎng)景一個(gè)班級(jí) 50 人學(xué)號(hào)連續(xù)用數(shù)組存查第 30 個(gè)學(xué)生很快但如果中途轉(zhuǎn)走 5 人、又轉(zhuǎn)入 3 人數(shù)組要移動(dòng)大量元素。學(xué)生立刻能感受到“插入刪除慢”這個(gè)痛點(diǎn)。然后我再引出鏈表說(shuō)明鏈表用指針把節(jié)點(diǎn)串起來(lái)插入刪除只需要改指針。講鏈表時(shí)我會(huì)把“帶頭節(jié)點(diǎn)”和“不帶頭節(jié)點(diǎn)”兩種寫法都演示一遍。很多教材默認(rèn)帶頭節(jié)點(diǎn)但學(xué)生自己寫的時(shí)候經(jīng)常混用導(dǎo)致刪除第一個(gè)節(jié)點(diǎn)時(shí)邏輯分叉。我的教案里統(tǒng)一用不帶頭節(jié)點(diǎn)因?yàn)楦庇^學(xué)生不容易在head是否為空上繞暈。等他們熟練了再介紹帶頭節(jié)點(diǎn)的寫法作為優(yōu)化。/* 刪除鏈表中第一個(gè)值為 target 的節(jié)點(diǎn)返回新的頭指針 */ Node* delete_node(Node *head, int target) { if (head NULL) return NULL; /* 空鏈表直接返回 */ if (head-data target) { /* 要?jiǎng)h的是頭節(jié)點(diǎn) */ Node *tmp head; head head-next; free(tmp); /* 釋放被刪節(jié)點(diǎn) */ return head; } Node *prev head; while (prev-next ! NULL prev-next-data ! target) { prev prev-next; /* 找目標(biāo)節(jié)點(diǎn)的前驅(qū) */ } if (prev-next ! NULL) { Node *tmp prev-next; prev-next tmp-next; /* 跳過(guò)被刪節(jié)點(diǎn) */ free(tmp); } return head; }參數(shù)說(shuō)明head是鏈表頭指針target是要?jiǎng)h除的值。邏輯分兩種情況刪頭節(jié)點(diǎn)和刪中間節(jié)點(diǎn)。學(xué)生常犯的錯(cuò)誤是刪頭節(jié)點(diǎn)后忘記更新head或者刪中間節(jié)點(diǎn)時(shí)沒(méi)有保存前驅(qū)。教案里我會(huì)讓學(xué)生先用紙筆畫一遍指針變化再上機(jī)寫。3.2 棧與隊(duì)列用數(shù)組和鏈表各實(shí)現(xiàn)一遍棧和隊(duì)列這一章我要求學(xué)生在同一節(jié)課里用數(shù)組和鏈表各實(shí)現(xiàn)一遍。原因是這兩種結(jié)構(gòu)最能體現(xiàn)“同樣的邏輯不同的存儲(chǔ)方式代碼差異在哪里”。熱搜里“單片機(jī)c語(yǔ)言沒(méi)有堆棧嗎為什么”這個(gè)問(wèn)題其實(shí)反映了很多嵌入式方向?qū)W生的困惑單片機(jī)里棧是硬件管理的和數(shù)據(jù)結(jié)構(gòu)課上的棧不是一回事。教案里我會(huì)專門用五分鐘解釋這個(gè)區(qū)別避免學(xué)生混淆。用數(shù)組實(shí)現(xiàn)棧核心是top指針用鏈表實(shí)現(xiàn)棧核心是頭插法。隊(duì)列用數(shù)組實(shí)現(xiàn)要注意循環(huán)隊(duì)列的front和rear關(guān)系用鏈表實(shí)現(xiàn)則要注意尾指針的維護(hù)。下面是一個(gè)循環(huán)隊(duì)列的入隊(duì)和出隊(duì)#define MAXSIZE 100 typedef struct { int data[MAXSIZE]; int front; /* 隊(duì)頭下標(biāo) */ int rear; /* 隊(duì)尾下標(biāo)指向下一個(gè)空位 */ } Queue; /* 入隊(duì)成功返回 1失敗返回 0 */ int enqueue(Queue *q, int value) { if ((q-rear 1) % MAXSIZE q-front) { return 0; /* 隊(duì)列已滿 */ } q-data[q-rear] value; q-rear (q-rear 1) % MAXSIZE; return 1; } /* 出隊(duì)成功返回 1 并寫入 value失敗返回 0 */ int dequeue(Queue *q, int *value) { if (q-front q-rear) { return 0; /* 隊(duì)列為空 */ } *value q-data[q-front]; q-front (q-front 1) % MAXSIZE; return 1; }參數(shù)說(shuō)明MAXSIZE是隊(duì)列容量實(shí)際最多存MAXSIZE - 1個(gè)元素因?yàn)橐粢粋€(gè)空位區(qū)分隊(duì)滿和隊(duì)空。front指向隊(duì)頭元素rear指向下一個(gè)空位。學(xué)生最容易錯(cuò)的是判斷隊(duì)滿的條件寫成rear MAXSIZE忘記取模。教案里我會(huì)讓學(xué)生手動(dòng)模擬入隊(duì) 5 次、出隊(duì) 3 次、再入隊(duì) 4 次把front和rear的變化畫在紙上。3.3 樹與二叉樹遍歷是唯一必須背下來(lái)的東西樹這一章概念多、術(shù)語(yǔ)多但真正必須背下來(lái)的只有三種遍歷的遞歸寫法和層序遍歷的隊(duì)列寫法。其他如線索二叉樹、哈夫曼樹可以放到后面作為選學(xué)。熱搜里“數(shù)據(jù)結(jié)構(gòu)知識(shí)點(diǎn)總結(jié)”經(jīng)常把樹的各種性質(zhì)列成表格但學(xué)生背了不會(huì)用。我的教案里樹的每一節(jié)課都從遍歷出發(fā)先寫前序、中序、后序再讓學(xué)生用遍歷解決實(shí)際問(wèn)題比如統(tǒng)計(jì)葉子節(jié)點(diǎn)數(shù)、求樹的高度。typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; /* 前序遍歷根 - 左 - 右 */ void preorder(TreeNode *root) { if (root NULL) return; printf(%d , root-data); preorder(root-left); preorder(root-right); } /* 統(tǒng)計(jì)葉子節(jié)點(diǎn)數(shù) */ int count_leaves(TreeNode *root) { if (root NULL) return 0; if (root-left NULL root-right NULL) return 1; return count_leaves(root-left) count_leaves(root-right); }參數(shù)說(shuō)明root是樹根指針允許為NULL。邏輯說(shuō)明前序遍歷先訪問(wèn)根再遞歸左右統(tǒng)計(jì)葉子節(jié)點(diǎn)時(shí)空樹返回 0葉子節(jié)點(diǎn)返回 1否則遞歸求和。學(xué)生常犯的錯(cuò)誤是忘記判斷root NULL導(dǎo)致空指針解引用。教案里我會(huì)讓學(xué)生先畫一棵三層的滿二叉樹手動(dòng)寫出三種遍歷序列再上機(jī)驗(yàn)證。3.4 排序冒泡、插入、快速排序的對(duì)比教學(xué)排序這一章熱搜里“冒泡排序c語(yǔ)言”“數(shù)據(jù)結(jié)構(gòu)排序算法”出現(xiàn)頻率極高說(shuō)明這是考試和面試的重災(zāi)區(qū)。我的教案里排序不按教材順序講而是按時(shí)間復(fù)雜度從差到好講先冒泡再插入再快速排序。每講一種都讓學(xué)生數(shù)比較次數(shù)和交換次數(shù)用具體數(shù)據(jù)感受差異。/* 冒泡排序升序 */ void bubble_sort(int arr[], int n) { for (int i 0; i n - 1; i) { int swapped 0; /* 標(biāo)記本趟是否發(fā)生交換 */ for (int j 0; j n - 1 - i; j) { if (arr[j] arr[j 1]) { int tmp arr[j]; arr[j] arr[j 1]; arr[j 1] tmp; swapped 1; } } if (!swapped) break; /* 本趟無(wú)交換已有序提前結(jié)束 */ } }參數(shù)說(shuō)明arr是待排序數(shù)組n是元素個(gè)數(shù)。邏輯說(shuō)明外層循環(huán)控制趟數(shù)內(nèi)層循環(huán)比較相鄰元素并交換swapped標(biāo)記用于提前退出。學(xué)生常犯的錯(cuò)誤是內(nèi)層循環(huán)邊界寫成j n - 1導(dǎo)致越界訪問(wèn)。教案里我會(huì)讓學(xué)生用{5, 3, 8, 1}手動(dòng)模擬每一趟的結(jié)果再上機(jī)驗(yàn)證??焖倥判虻闹v法不同我會(huì)先講 partition 的思路再寫遞歸。學(xué)生最難理解的是“基準(zhǔn)值歸位”這個(gè)動(dòng)作所以我會(huì)用動(dòng)畫或紙牌演示一遍。4. 避坑與排查教案落地時(shí)最容易翻車的五件事4.1 學(xué)生環(huán)境不統(tǒng)一代碼在別人機(jī)器上跑不起來(lái)現(xiàn)象你在投影上跑通的代碼學(xué)生復(fù)制到自己電腦上編譯報(bào)錯(cuò)提示undefined reference to malloc或者中文亂碼。原因Windows 下用 Dev-C、VS Code、Visual Studio 的編譯選項(xiàng)不同scanf的安全檢查、源文件編碼、main返回值都可能不一致。解決教案里固定一套環(huán)境我一般推薦 VS Code MinGW-w64并在第一節(jié)課帶學(xué)生配置tasks.json和launch.json。熱搜里“vscode配置c語(yǔ)言環(huán)境”是個(gè)高頻需求說(shuō)明這個(gè)問(wèn)題非常普遍。配置好后讓學(xué)生編譯一個(gè)空main確認(rèn)環(huán)境可用再開始寫數(shù)據(jù)結(jié)構(gòu)。4.2 指針畫圖會(huì)寫代碼就懵現(xiàn)象學(xué)生在紙上能畫出鏈表插入的指針變化但一寫代碼就寫成head-next new_node然后崩潰。原因畫圖時(shí)用的是“箭頭”寫代碼時(shí)忘了箭頭對(duì)應(yīng)的是-next還是next以及操作順序不能顛倒。解決教案里強(qiáng)制要求“先寫注釋再寫代碼”。比如插入節(jié)點(diǎn)前先寫三行注釋// 1. 新節(jié)點(diǎn)指向原頭、// 2. 原頭的前驅(qū)更新、// 3. 更新頭指針再逐行翻譯成代碼。這個(gè)習(xí)慣能減少一半以上的指針錯(cuò)誤。4.3 實(shí)驗(yàn)報(bào)告抄網(wǎng)上的異常分析千篇一律現(xiàn)象收上來(lái)的實(shí)驗(yàn)報(bào)告異常分析都寫“指針使用不熟練導(dǎo)致錯(cuò)誤”沒(méi)有具體信息。原因?qū)W生沒(méi)有真正調(diào)試或者調(diào)試了但不知道怎么描述。解決教案里給一個(gè)異常分析的模板要求寫清楚“錯(cuò)誤現(xiàn)象、定位方法、根本原因、修復(fù)方式”四要素。比如“程序輸出亂碼用gdb斷點(diǎn)發(fā)現(xiàn)head為NULL時(shí)仍執(zhí)行了head-next原因是刪除節(jié)點(diǎn)前未判空修復(fù)方式是加if (head NULL) return NULL;”。這樣學(xué)生有章可循報(bào)告質(zhì)量明顯提升。4.4 課時(shí)不夠講不完所有數(shù)據(jù)結(jié)構(gòu)現(xiàn)象48 學(xué)時(shí)上到圖論就只剩 4 周學(xué)生還沒(méi)消化樹就要考試。原因教案按教材目錄平均分配課時(shí)沒(méi)有區(qū)分“必講”和“選講”。解決教案里把章節(jié)標(biāo)成三類核心線性表、棧隊(duì)列、樹、排序、重要查找、圖的基本概念、選學(xué)平衡樹、B 樹、最短路徑的復(fù)雜實(shí)現(xiàn)。核心章節(jié)必須留足上機(jī)時(shí)間選學(xué)章節(jié)只講概念和偽代碼不要求手寫完整實(shí)現(xiàn)。熱搜里“408數(shù)據(jù)結(jié)構(gòu)考研知識(shí)點(diǎn)”和“數(shù)據(jù)結(jié)構(gòu)期末復(fù)習(xí)”的訴求不同教案要能同時(shí)服務(wù)這兩類人就得做分層。4.5 學(xué)生用 AI 生成代碼看不懂也交上來(lái)現(xiàn)象實(shí)驗(yàn)課上有學(xué)生提交的代碼風(fēng)格統(tǒng)一、注釋完整但提問(wèn)時(shí)說(shuō)不清malloc和free的配對(duì)關(guān)系。原因直接復(fù)制了生成式工具的輸出沒(méi)有自己調(diào)試。解決教案里增加“代碼答辯”環(huán)節(jié)隨機(jī)抽學(xué)生解釋某一行代碼的作用或者要求現(xiàn)場(chǎng)修改一個(gè)參數(shù)看輸出變化。比如把insert_head改成insert_tail看學(xué)生能否獨(dú)立完成。這個(gè)環(huán)節(jié)不占太多時(shí)間但能有效篩出沒(méi)動(dòng)手的人。5. 進(jìn)階技巧用“最小可運(yùn)行示例”串起整門課教了幾年之后我最大的習(xí)慣是每節(jié)課只留一個(gè)最小可運(yùn)行示例但要求學(xué)生在上面做三次修改。比如鏈表這節(jié)課示例是insert_head三次修改分別是改成尾插、增加按值刪除、增加按值查找。每次修改都只動(dòng)一個(gè)函數(shù)學(xué)生不會(huì)因?yàn)榇a量太大而放棄。這個(gè)習(xí)慣來(lái)自一次血淚教訓(xùn)早年我每節(jié)課給一個(gè)兩百行的完整示例結(jié)果學(xué)生只顧著抄沒(méi)人真正理解指針怎么走。進(jìn)階用法上我建議把整門課的示例代碼放在一個(gè)倉(cāng)庫(kù)里按章節(jié)分目錄每個(gè)目錄一個(gè)Makefile。學(xué)生 clone 下來(lái)后make就能編譯運(yùn)行。這樣他們可以把精力放在邏輯上而不是環(huán)境配置上。下面是一個(gè)極簡(jiǎn)的Makefile適合單文件示例CC gcc CFLAGS -Wall -g -stdc11 TARGET list_demo SRCS list_demo.c $(TARGET): $(SRCS) $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) clean: rm -f $(TARGET)參數(shù)說(shuō)明-Wall打開所有警告-g保留調(diào)試信息-stdc11指定 C 標(biāo)準(zhǔn)。學(xué)生如果編譯報(bào)錯(cuò)先看警告信息大部分指針問(wèn)題-Wall都能提示。make clean用于清理可執(zhí)行文件。這個(gè)Makefile可以直接復(fù)用到棧、隊(duì)列、樹的示例上只需改TARGET和SRCS。驗(yàn)證教案是否有效我只看一個(gè)指標(biāo)學(xué)生能否在期末獨(dú)立寫出一個(gè)帶頭節(jié)點(diǎn)的單鏈表并完成插入、刪除、查找、反轉(zhuǎn)四個(gè)操作且通過(guò)valgrind內(nèi)存檢查。如果能這門課就沒(méi)白教。如果不行問(wèn)題一定出在教案的某個(gè)環(huán)節(jié)沒(méi)有讓學(xué)生動(dòng)手而不是學(xué)生太笨。我自己現(xiàn)在寫教案每學(xué)期都會(huì)刪掉一個(gè)“講得很爽但學(xué)生沒(méi)動(dòng)手”的環(huán)節(jié)換成一個(gè)“學(xué)生必須敲代碼”的環(huán)節(jié)。這個(gè)習(xí)慣讓我從“講得好的老師”變成“學(xué)生能學(xué)會(huì)的老師”。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取