作業資訊
這個作業屬於哪個課程 | 2024-2025-1-計算機基礎與程式設計) |
---|---|
這個作業要求在哪裡 | https://www.cnblogs.com/rocedu/p/9577842.html#WEEK07 |
這個作業的目標 | 陣列與連結串列 基於陣列和基於連結串列實現資料結構 無序表與有序表 樹 圖 子程式與引數 |
作業正文 | https://www.cnblogs.com/tanzitian11/p/18537336 |
教材學習內容總結
電腦科學與概論
1. 抽象資料型別與子程式
1.抽象資料型別:抽象資料型別(Abstract Data Type,簡稱 ADT)是指一個數學模型以及定義在該模型上的一組操作。它是對資料型別的一種抽象描述,只關注資料的邏輯特性和操作,而不考慮具體的實現細節。
2. 資料結構:是一種儲存和組織資料的方式,以便能夠高效地訪問和運算元據。它不僅涉及資料的儲存方式,還包括對資料進行的各種操作,如插入、刪除、查詢等。
3.容器:容器是一種儲存和管理資料的物件,通常提供了一組操作來方便地插入、刪除、查詢和遍歷資料。容器可以看作是一種更高層次的資料結構,它通常基於現有的資料結構實現,並提供了更方便的介面和功能。
4.佇列:計算機佇列是一種特殊的線性資料結構,遵循先進先出(FIFO,First In First Out)的原則。它在電腦科學的各個領域都有廣泛的應用。
一、佇列的組成
隊頭(front):指向佇列中第一個元素的位置。
隊尾(rear):指向佇列中最後一個元素的下一個位置。
元素集合:儲存在佇列中的資料元素。
二、佇列的基本操作
入隊(enqueue):將一個元素新增到佇列的隊尾。
操作步驟:首先將隊尾指標 rear 向後移動一個位置,然後將新元素放入 rear 所指的位置。
但在某些特殊情況下可能需要重新分配記憶體,此時時間複雜度可能為 O (n)。
出隊(dequeue):從佇列的隊頭刪除一個元素。
操作步驟:取出隊頭元素,然後將隊頭指標 front 向後移動一個位置。
檢視隊頭元素(peek):返回佇列的隊頭元素,但不刪除它。
判斷佇列是否為空(isEmpty):檢查佇列中是否沒有元素。
判斷佇列是否已滿(isFull):對於有固定大小的佇列,檢查佇列是否已滿。
5.列表:
一、概念
列表是一種常見的資料結構,它是由一組有序的元素組成。
二、特點
1.有序性
列表中的元素是按照特定的順序排列的,這個順序可以是插入的順序,也可以是根據某種規則進行排序後的順序。
你可以透過索引來訪問列表中的特定元素,這使得在需要按照特定順序處理資料時非常方便。
2.可變性
列表通常是可變的,這意味著你可以新增、刪除或修改列表中的元素。
這種可變性使得列表在處理動態資料集合時非常有用,比如在使用者輸入不斷變化的情況下。
3.多樣性
列表可以儲存不同型別的元素,比如整數、字串、物件等。
這使得列表在儲存和處理複雜資料結構時非常靈活。
6.樹:
一、定義與基本概念
樹是由 n(n≥0)個節點組成的有限集合。當 n = 0 時,稱為空樹。在一棵非空樹中:
有一個特定的稱為根(root)的節點。
當 n > 1 時,其餘節點可分為 m(m > 0)個互不相交的有限集合 T1、T2、……、Tm,其中每一個集合本身又是一棵樹,並且稱為根的子樹。
二、樹的特點
層次性:樹具有明顯的層次結構,從根節點開始,逐漸向下分支形成子樹。
非線性:與線性資料結構(如陣列、連結串列)不同,樹的節點之間不是簡單的線性關係。
一對多關係:除了根節點外,每個節點有且僅有一個父節點,但可以有零個或多個子節點。
三、常見型別的樹
二叉樹:每個節點最多有兩個子樹的樹結構。
滿二叉樹:所有葉節點都在同一層,並且每個非葉節點都有兩個子節點。
完全二叉樹:除了最後一層,其他各層的節點數都達到最大,並且最後一層的節點從左到右依次排列。
二叉搜尋樹:對於二叉搜尋樹中的任意一個節點,其左子樹中的所有節點的值都小於該節點的值,右子樹中的所有節點的值都大於該節點的值。
平衡二叉樹:是一種特殊的二叉搜尋樹,它的左右子樹的高度差不超過 1,以保證樹的查詢、插入和刪除操作的時間複雜度為 O (log n)。
哈夫曼樹:也叫最優二叉樹,用於資料壓縮等領域。它是帶權路徑長度最短的二叉樹。
四、樹的基本操作
插入節點:將一個新節點插入到樹中的合適位置。在二叉搜尋樹中,根據節點的值與當前節點的值的比較結果,決定將新節點插入到左子樹還是右子樹。
刪除節點:從樹中刪除一個指定的節點。刪除節點的操作相對複雜,需要考慮被刪除節點的位置和子樹的情況。
查詢節點:在樹中查詢具有特定值的節點。根據樹的結構特點,可以採用不同的查詢演算法。
遍歷樹:遍歷樹是指按照一定的順序訪問樹中的所有節點。常見的遍歷方式有前序遍歷、中序遍歷、後序遍歷和層次遍歷
7.圖:
一、定義與基本概念
圖由頂點(vertex)和邊(edge)組成。頂點也稱為節點,邊則是連線兩個頂點的線段。如果邊是有方向的,則稱為有向圖;如果邊沒有方向,則稱為無向圖。
二、圖的表示方法
鄰接矩陣:用一個二維矩陣來表示圖。矩陣的行和列分別對應圖中的頂點。如果兩個頂點之間有邊相連,則矩陣中對應的元素為 1(或邊的權重);如果沒有邊相連,則元素為 0。
優點:可以快速判斷兩個頂點之間是否有邊相連,以及獲取邊的權重。
缺點:對於稀疏圖(邊的數量相對較少的圖),會浪費大量的儲存空間。
鄰接表:為每個頂點建立一個連結串列,連結串列中儲存與該頂點相鄰的頂點。
優點:對於稀疏圖,儲存空間效率高。
缺點:判斷兩個頂點之間是否有邊相連需要遍歷連結串列,相對較慢。
三、圖的基本操作
插入頂點:向圖中新增一個新的頂點。
插入邊:在兩個頂點之間新增一條邊。對於有向圖,需要指定邊的起點和終點;對於無向圖,邊是雙向的。
刪除頂點:從圖中移除一個頂點,並刪除與該頂點相關的所有邊。
刪除邊:從圖中移除一條邊。
遍歷圖:有多種遍歷方式,如深度優先遍歷和廣度優先遍歷。
深度優先遍歷:從一個頂點開始,沿著一條路徑儘可能深地探索,直到無法繼續前進,然後回溯到上一個頂點,繼續探索其他路徑。
廣度優先遍歷:從一個頂點開始,先訪問該頂點的所有相鄰頂點,然後再依次訪問這些相鄰頂點的相鄰頂點,直到遍歷完整個圖。
8.子程式:
一、定義與概念
子程式,也稱為函式、方法或過程,是一段可重複使用的程式碼塊,用於完成特定的任務。它可以接受輸入引數(也稱為自變數),並返回一個結果(如果有返回值的話)。
二、特點
程式碼複用:子程式的主要目的之一是實現程式碼複用。透過將一段常用的程式碼封裝成子程式,可以在多個地方呼叫它,避免重複編寫相同的程式碼。
模組化:子程式將複雜的任務分解為較小的、易於管理的模組。每個子程式專注於完成一個特定的功能,使得程式的結構更加清晰,易於維護和擴充套件。
引數傳遞:子程式可以接受輸入引數,這些引數可以是不同型別的資料,如整數、字串、物件等。透過引數傳遞,子程式可以根據不同的輸入執行不同的操作。
返回值:子程式可以返回一個結果給呼叫者。返回值可以是任何資料型別,取決於子程式的功能。
三、作用與優勢
提高開發效率:透過複用已有的子程式,可以減少開發時間和工作量。開發人員可以專注於編寫新的功能,而不必重複實現已經存在的功能。
增強程式碼可讀性:將複雜的任務分解為多個子程式,每個子程式具有明確的功能和名稱,使得程式碼更易於理解和閱讀。其他開發人員可以更容易地理解程式的邏輯結構,並進行維護和擴充套件。
便於除錯和測試:由於子程式是獨立的程式碼塊,可以單獨進行除錯和測試。這有助於更快地發現和修復錯誤,提高程式的質量。
可維護性:當需要修改程式的功能時,如果該功能是透過子程式實現的,只需要修改相應的子程式即可,而不會影響到其他部分的程式碼。這使得程式的維護更加容易。
四、呼叫方式
直接呼叫:在程式中直接使用子程式的名稱,並傳遞相應的引數來呼叫它。例如,在 Python 中,可以使用function_name(parameter1, parameter2)的方式呼叫一個函式。
間接呼叫:透過指標、引用或函式物件等方式間接呼叫子程式。這種方式在一些高階程式設計技術中經常使用,如函式指標、回撥函式等。
五、引數傳遞方式
值傳遞:將引數的值複製一份傳遞給子程式。在子程式中對引數的修改不會影響到原始引數的值。
引用傳遞:將引數的引用(記憶體地址)傳遞給子程式。在子程式中對引數的修改會影響到原始引數的值。
指標傳遞:與引用傳遞類似,透過傳遞引數的指標來實現引數的傳遞。在子程式中可以透過指標間接修改引數的值。
c語言程式設計
迴圈控制結構:
在計算機程式設計中,迴圈控制結構是一種重要的控制結構,用於重複執行一段程式碼塊,直到滿足特定的條件為止。
一、常見的迴圈控制結構型別
for迴圈:
for迴圈通常用於已知迴圈次數的情況。它有三個部分:初始化部分、迴圈條件部分和迭代部分。
例如,在 C 語言中,for (int i = 0; i < 10; i++) { // 迴圈體 },這裡初始化了一個變數i為 0,迴圈條件是i < 10,每次迴圈後i自增 1。
for迴圈在很多程式語言中都非常常見,如 Java、Python、JavaScript 等。
while迴圈:
while迴圈在執行迴圈體之前先判斷條件,如果條件為真,則執行迴圈體;如果條件為假,則跳出迴圈。
例如,在 C 語言中,while (condition) { // 迴圈體 }。只要condition為真,迴圈就會一直執行。
while迴圈適用於不確定迴圈次數的情況,因為迴圈條件可以根據程式的執行情況動態變化。
do-while迴圈:
do-while迴圈先執行一次迴圈體,然後再判斷條件。如果條件為真,則繼續執行迴圈體;如果條件為假,則跳出迴圈。
例如,在 C 語言中,do { // 迴圈體 } while (condition);。
do-while迴圈至少會執行一次迴圈體,這在某些情況下非常有用。
二、迴圈控制的關鍵要素
迴圈條件:
迴圈條件是決定迴圈是否繼續執行的關鍵。它通常是一個布林表示式,當表示式的值為真時,迴圈繼續執行;當表示式的值為假時,迴圈結束。
迴圈條件應該在迴圈的執行過程中能夠被改變,否則可能會導致無限迴圈。
迴圈體:
迴圈體是迴圈控制結構中重複執行的程式碼塊。它可以包含任何合法的程式語言語句,如賦值語句、條件語句、函式呼叫等。
迴圈體的執行次數取決於迴圈條件的判斷結果。
迴圈變數:
在for迴圈和一些while迴圈中,通常會使用一個迴圈變數來控制迴圈的執行次數或遍歷一個資料集合。
迴圈變數的初始值、更新方式和終止條件都是迴圈控制的重要組成部分。
例子:程式設計從鍵盤輸入n,計算並輸出1+2+3+……+n的值。
#include<stdio.h> int main(void) { int i,n; int sum=0; scanf("%d",&n); for(i=1;i<=n;i++) { sum=sum+i; } printf("%d",sum); return 0; }
一、計數迴圈的基本結構
在大多數程式語言中,計數迴圈通常使用for迴圈來實現。其基本結構如下:
for (初始化計數器; 迴圈條件; 更新計數器) {
// 迴圈體
}
初始化計數器:在迴圈開始之前,設定計數器的初始值。這個初始值通常是一個整數,表示迴圈的起始點。
迴圈條件:這是一個布林表示式,用於判斷是否繼續執行迴圈。只要迴圈條件為真,迴圈就會繼續執行;當迴圈條件為假時,迴圈結束。
更新計數器:在每次迴圈結束後,更新計數器的值。這個更新操作通常是遞增或遞減計數器,以控制迴圈的執行次數。
迴圈體:這是在迴圈中重複執行的程式碼塊。它可以包含任何合法的程式語言語句,用於實現特定的任務。
二、計數迴圈的控制方法
設定正確的初始值和迴圈條件:
初始值應該根據具體的需求來設定,確保迴圈從正確的起點開始。
迴圈條件應該能夠準確地控制迴圈的執行次數。例如,如果要執行迴圈 10 次,可以設定迴圈條件為計數器小於 10。
注意避免設定錯誤的初始值和迴圈條件,以免導致無限迴圈或迴圈次數不正確的問題。
選擇合適的計數器更新方式:
計數器的更新方式可以是遞增(如i++)或遞減(如i--),具體取決於迴圈的需求。
如果要從某個值開始逐漸增加到另一個值,可以使用遞增方式;如果要從某個值開始逐漸減少到另一個值,可以使用遞減方式。
還可以根據具體情況選擇其他的更新方式,如每次增加或減少一個特定的值。
控制迴圈體中的操作:
在迴圈體中,可以執行各種操作,但要注意這些操作不要影響迴圈的控制條件。
例如,如果在迴圈體中修改了計數器的值,可能會導致迴圈的執行次數不正確。
確保迴圈體中的操作是合理的,並且不會破壞迴圈的控制邏輯。
考慮迴圈的退出條件:
除了迴圈條件之外,還可以在迴圈體中設定其他的退出條件。例如,如果在迴圈過程中滿足了某個特定的條件,可以使用break語句立即退出迴圈。
這樣可以在必要時提前結束迴圈,提高程式的效率。
一、巢狀迴圈的基本結構
以下是在大多數程式語言中巢狀迴圈的一般形式:
for (外迴圈初始化; 外迴圈條件; 外迴圈更新) {
// 外迴圈體
for (內迴圈初始化; 內迴圈條件; 內迴圈更新) {
// 內迴圈體
}
}
在這個結構中,外迴圈控制著整個巢狀迴圈的執行次數,而內迴圈在每次外迴圈迭代中都會完整地執行一遍。
二、巢狀迴圈的特點
執行順序
巢狀迴圈的執行順序是先執行外迴圈的一次迭代,然後在該迭代中執行內迴圈的所有迭代。接著,外迴圈進行下一次迭代,再次執行內迴圈的所有迭代,以此類推。
例如,如果外迴圈執行 3 次,內迴圈執行 4 次,那麼內迴圈體總共會執行 3×4 = 12 次。
迴圈變數的作用域
外迴圈和內迴圈可以有各自獨立的迴圈變數,它們的作用域分別在各自的迴圈體內。
但是,在一些程式語言中,如果不小心使用了相同的變數名,可能會導致變數衝突和錯誤的結果。
控制流程
可以在巢狀迴圈中使用break和continue語句來控制迴圈的執行流程。
break語句可以立即退出當前迴圈(內迴圈或外迴圈,具體取決於其在哪個迴圈中使用)。
continue語句可以跳過當前迴圈的剩餘部分,直接進入下一次迭代。
一、條件控制迴圈的基本結構和原理
條件控制的迴圈通常使用while迴圈或do-while迴圈來實現。其基本結構如下:
while迴圈:
while (條件表示式) {
// 迴圈體
}
在while迴圈中,首先判斷條件表示式的值。如果條件表示式為真,則執行迴圈體中的程式碼;然後再次判斷條件表示式的值,重複這個過程,直到條件表示式為假為止。
do-while迴圈:
do {
// 迴圈體
} while (條件表示式);
do-while迴圈與while迴圈類似,但它會先執行一次迴圈體,然後再判斷條件表示式的值。如果條件表示式為真,則繼續執行迴圈體;否則,迴圈結束。
二、條件表示式的重要性
條件表示式是條件控制的迴圈的核心部分,它決定了迴圈是否繼續執行。條件表示式通常是一個布林表示式,其結果為真或假。在編寫條件表示式時,需要考慮以下幾個方面:
初始條件:在進入迴圈之前,需要確保條件表示式的初始值為真,否則迴圈將不會執行。
迴圈更新:在迴圈體中,需要確保對條件表示式的值進行更新,以便在適當的時候結束迴圈。如果條件表示式的值始終為真,將會導致無限迴圈。
邊界條件:需要考慮迴圈的邊界條件,以確保迴圈在正確的情況下結束。例如,如果迴圈是用於遍歷一個陣列,需要確保在到達陣列末尾時結束迴圈。
流程的控制與轉移
跳轉語句
break語句:
用於跳出迴圈或switch語句。
例如,在迴圈中,當滿足某個條件時,可以使用break跳出迴圈:while (true) {if (condition) {break;} }。
continue語句:
用於跳過當前迴圈的剩餘部分,直接進入下一次迴圈。
例如,在迴圈中,當滿足某個條件時,可以使用continue跳過本次迴圈:while (i < 10) {if (i % 2 == 0) {continue;} printf("%d ", i); i++;}。
goto語句:
可以無條件地跳轉到程式中的某個標籤處。但由於goto語句會使程式的流程變得混亂,難以理解和維護,所以一般不推薦使用。
例如:goto label;... label: printf("跳轉到此");。
結構化程式設計的核心思想
一、自頂向下
含義
從程式的總體功能出發,將一個複雜的問題逐步分解為若干個較小的子問題,然後再對每個子問題進行進一步的分解,直到問題變得足夠簡單,可以直接用程式語句來實現。
這種方法使得程式設計師能夠更好地理解和把握整個程式的結構和邏輯,從而提高程式的可讀性、可維護性和可擴充套件性。
示例
例如,要開發一個學生成績管理系統,可以先將其分解為學生資訊管理、課程資訊管理、成績錄入、成績查詢等幾個子模組。然後,再對每個子模組進行進一步的細分,如學生資訊管理可以分為學生資訊錄入、學生資訊修改、學生資訊刪除等功能。
二、逐步求精
含義
在自頂向下分解問題的過程中,對每個子問題進行逐步細化,不斷增加細節,直到可以用具體的程式語句來實現。
這種方法可以幫助程式設計師避免一開始就陷入細節,從而更好地把握程式的整體結構和邏輯。
示例
以學生資訊錄入功能為例,可以先確定需要錄入的學生資訊包括姓名、學號、性別、年齡等基本資訊。然後,再考慮如何輸入這些資訊,如何進行資料驗證,如何儲存這些資訊等細節問題。
三、模組化
含義
將程式分解為若干個獨立的模組,每個模組完成一個特定的功能。模組之間透過介面進行互動,模組內部的實現細節對其他模組是隱藏的。
這種方法可以提高程式的可維護性和可擴充套件性,因為當需要修改某個功能時,只需要修改相應的模組,而不會影響其他模組。
示例
在學生成績管理系統中,可以將學生資訊管理、課程資訊管理、成績錄入、成績查詢等功能分別封裝成不同的模組。每個模組都有自己的輸入、輸出和處理邏輯,模組之間透過函式呼叫或引數傳遞進行互動。
四、限制使用 goto 語句
含義
goto 語句可以無條件地跳轉到程式中的任何位置,這會使程式的流程變得混亂,難以理解和維護。因此,結構化程式設計主張限制使用 goto 語句,儘量使用順序、選擇和迴圈三種基本控制結構來構造程式。
示例
例如,在 C 語言中,可以使用if語句、switch語句、while迴圈、for迴圈等控制結構來實現程式的流程控制,而避免使用goto語句。
基於AI的學習
程式碼除錯中的問題和解決過程
-
問題1:求最大公約數的時候忘記公式了
int gcd(int a,int b)
{
if(b==0){
return a;
}else {
return gcd(b,a%b);
} -
問題1解決方案:又回去複習了輾轉相除法。
學習進度條
程式碼行數(新增/累積) | 部落格量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第四周 | 200/200 | 1/2 | 20/20 | |
第五週 | 300/500 | 1/4 | 18/38 | |
第六週 | 500/1000 | 1/7 | 22/60 | |
第七週 | 300/1300 | 1/9 | 14/90 |