- C#實踐教程(第2版)
- 李乃文
- 3644字
- 2021-03-19 18:15:41
4.2 一維數組
一維數組是數組中最為簡單和常用的,由單個數據為成員構成的數組。如季節數組可以包含4個成員:春、夏、秋、冬。數組中的每一個元素都可以作為一個變量被訪問。
4.2.1 一維數組簡介
一維數組的聲明同變量聲明類似,聲明中需要包含成員的數據類型和數組名,不同的是數組聲明需要在數據類型后緊跟著一個中括號[]。如聲明一個名為num的數組,使用代碼如下:
int[] num;
上述代碼中,int關鍵字指定該數組中的成員為int型的數據,int后面的中括號除了用于與其他變量或常量區分,還用于定義數組的長度,即數組中的元素數量。
int關鍵字與中括號之間沒有空格,而中括號與數組名稱之間有一個空格。數組需要初始化才能使用,這一點與變量的使用一樣。
數組的長度需要在初始化時指定,可以將長度寫在中括號中,也可為數組成員賦值,系統將根據數組的賦值為數組分配空間、確定數組的長度。如定義一個有著3個整型元素的數組num,格式如下:
int[] num=new int[3];
數組的賦值需要將數組成員放在{}內,每個元素之間用逗號隔開。如將數組變量num直接賦值,格式如下:
int[] num={1,2,3};
上述代碼中,對數組的賦值,可將數組成員放在大括號“{}”中,每個成員之間使用逗號隔開。數組成員賦值時,其內部的成員必須符合數組的數據類型。數組元素也可以是變量,如分別定義整型變量a、b、c,并賦給數組num,格式如下:
int a, b, c; a = 0; b = 0; c = 0; int[] num = { a, b, c };
除了數組在聲明時的直接賦值,數組在聲明后不能直接賦值,而需要實例化后才能賦值。使用關鍵字new,如練習4-1所示。
【練習4-1】
聲明整型數組num,實例化數組的長度為3,并賦值為{55,9,7},使用代碼如下:
int[] num; num=new int[3]{55,9,7};
不能直接像變量賦值一樣使用代碼num={55,9,7};進行賦值。即使是使用new將對象實例化,也不能使用這樣的語句。但是可以對實例化的數組成員單獨賦值。即數組賦值只有三種形式:
□ 在聲明時直接賦值。
□ 程序進行時使用new賦值。
□ 在數組被實例化后,對數組成員單獨賦值。
由于一個數組有多個成員的排列,因此為確定到具體的一個成員,數組中有索引的概念。索引相當于圖書的目錄,為指定的內容標注一個方向。數組中的索引相當于其成員的編號,數組中的第一個成員索引為0,第二個成員索引為1,第n個成員的索引為n-1。使用索引來訪問數組成員,如訪問練習4-1中的第2個成員9,輸出該成員的值,使用如下語句:
Console.Write(num[1]);
上述代碼中,使用num[1]訪問num數組的第2個成員9,其構成為:數組名、中括號、中括號內部的索引。這3個構成成分之間不需要有空格,上述代碼的執行結果為9。
數組實際是類的一個對象,是基類Array的派生,可以使用Array的成員,如Length屬性。關于類、對象、基類和派生等內容將在第5章和第6章介紹,本節只需學會如何使用Length屬性獲取數組長度。如獲取數組num的長度并賦值給longnun,格式如下:
int longnum = num.Length;
4.2.2 數組遍歷
數組的遍歷即依照索引順序,依次訪問所有數組成員。數組的遍歷可以使用循環語句,包括for循環、while循環等,以及專用于數組和數據集合的foreach in語句。
使用循環語句遍歷數組,如為數組賦值或使用數組中的數據為其他變量賦值,如練習4-2所示。
【練習4-2】
聲明整型數組num,實例化數組的長度為10,并將其成員依次賦值為1到10,使用代碼如下:
int[] num; num = new int[10]; for (int i = 0; i < num.Length;i++ ) { num[i] = i + 1; } for (int i = 0; i < num.Length; i++) { Console.Write("{0} ",num[i]); }
執行結果為:
1 2 3 4 5 6 7 8 9 10
練習4-2使用第1個for循環將數組賦值,又使用第2個for循環輸出數組的值。使用循環語句遍歷數組方便、容易理解,C#提供了數組專用的遍歷語句foreach in語句,在本書第3章簡單提過,使用方法如練習4-3所示。
【練習4-3】
將數組num1賦值為{5,2,6,8,4,1,3,9,7},使用foreach in語句將數組成員輸出,代碼如下:
int[] num1 = { 5, 2, 6, 8, 4, 1, 3, 9, 7 }; foreach(int i in num1) { Console.Write("{0} ",i); }
執行結果為:
5 2 6 8 4 1 3 9 7
foreach in語句結構簡單,在數組中的作用就是將數組成員順序遍歷。
4.2.3 數組排序
數組最常見的應用就是對數組成員的排序,這也是生活中對數據的重要處理。如將全班學生的成績賦值給數組,并按成績從大到小排列。
數組的排序將改變數組成員的原有索引,如將數組成員按照從小到大的順序排序,則數組中數字最小的成員,在排序后,其索引被修改為0。常見的排序方式有以下幾種。
□ 冒泡排序 將數據按一定順序一個一個傳遞到應有位置。
□ 選擇排序 選出需要的數據與指定位置數據交換。
□ 插入排序 在順序排列的數組中插入新數據。
1. 冒泡排序
冒泡排序是最穩定的,也是遍歷次數最多的排序方式。例如,將n個元素的數組數據從小到大排序:
冒泡排序將按照序號將數組中的相鄰數據進行比較,每一次比較后將較大的數據放在后面。所有數據執行一遍之后,最大的數據在最后面。接著再進行一遍,直到進行n次,確保數據順序排列完成,如練習4-4所示。
【練習4-4】
將數組value賦值為{15,4,1,2,8,33,22,26,30,19},通過冒泡排序將數組成員按從小到大的順序排序,代碼如下:
int[] value = { 15, 4, 1, 2, 8, 33, 22, 26, 30, 19 }; int max=0; for (int i = 9; i >= 0;i-- ) { for (int j = 0; j <i; j++) { if (value[j] > value[j + 1]) { max = value[j]; value[j]=value[j+1]; value[j+1]=max; } } } foreach (int i in value) { Console.Write("{0} ", i); }
執行結果為:
1 2 4 8 15 19 22 26 30 33
練習4-4通過內部循環將最大值一點一點移動到數組最后的位置。冒泡排序每移動一個最大值,接下來可以減少一次比較移動。因此,內部循環每執行一遍,執行次數減少一次。
冒泡排序準確性高,但執行語句多,數組要進行的比較和移動次數多。冒泡排序不會破壞相同數值元素的先后順序,被稱作是穩定排序。
2. 選擇排序
選擇排序為數組每一個位置選擇合適的數據,如將數組從小到大排序,選擇排序給第一個位置選擇最小的,在剩余元素里面給第二個元素選擇第二小的,以此類推,直到第n-1個元素,第n個元素不用選擇了。
將數組按從小到大排序,選擇排序將第一個元素視為最小的,分別與其他元素比較;當其他元素小于第一個元素,則交換它們的位置,并繼續跟剩下的元素比較。直到確定第一個元素是最小的,再從第二個元素比較。直到倒數第二個元素與最后一個元素比較,如練習4-5所示。
【練習4-5】
將數組score賦值為{75,69,89,72,99,86,93,88,84,77},通過選擇排序法將數組成員按從小到大的順序排序,代碼如下:
int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }; int max; for (int i = 9; i >= 0; i--) { for (int j = 0; j < i; j++) { if (score[j] > score[i]) { max = score[j]; score[j] = score[i]; score[i] = max; } } } foreach (int i in score) { Console.Write("{0} ", i); }
執行結果為:
69 72 75 77 84 86 88 89 93 99
練習4-5中將數組序號從小到大依次與最后一個元素比較,將較大值與最后一個元素交換數值,得到最后位置上的數值;接著將元素依次與倒數第二個元素比較,以此類推,直到與第2個數比較。
選擇排序改變了數值相同元素的先后順序,屬于不穩定的排序。選擇排序同樣進行了較多的比較和移動。
4.2.4 插入數組元素
數組新元素的插入,將導致插入位置之后的元素依次改變原有序號。在指定位置插入新的元素,為保證原有元素的穩定,首先要將原有元素移位,再將新的元素插入指定位置。
插入時元素的移位與排序時的移位不同,插入使得數組改變了原有長度,存儲數組的空間不足以讓新元素的加入。
使用new關鍵字可以修改數組的長度,但這種修改相當于重新定義了數組,數組元素的值將會被定為默認值0,如練習4-6所示。
【練習4-6】
將數組int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }重新聲明為11個值,并輸出,代碼如下:
int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }; score = new int[11]; foreach (int j in score) { Console.Write("{0} ", j); }
輸出結果為:
0 0 0 0 0 0 0 0 0 0 0
可見數組的重新定義將失去原有元素值,只能通過新建數組來保存插入后的數組,如練習4-7所示。
【練習4-7】
將數組score的第(n+1)個位置插入數據73,使其成為新的數組score1,即score1[n]=73,實現代碼如下:
int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }; int[] score1 = new int[11]; int n = 5; //在第n+1位置插入 int addnum = 73; //插入數值73 for (int i = 9; i >=n; i--) { score1[i + 1] = score[i]; if (i == n) { score1[n] = addnum; for (int j = n - 1; j >= 0; j--) { score1[j] = score[j]; } break; } } foreach (int j in score1) { Console.Write("{0} ", j); }
運行結果如下:
75 69 89 72 99 73 86 93 88 84 77
與原數組相比,第6個位置,原來86所在的位置插入了73。插入排序法在比較的基礎上進行插入。
插入排序法是在一個有序的數組基礎上,依次插入一個元素。如將數組從小到大排序,將新元素與有序數組的最大值比較,若新元素大,插入到字段末尾;否則與倒數第二個元素比較,直到找到它的位置,此時需要將該位置及該位置之后的元素序號發生改變,需要重新調整。
插入排序沒有改變相同元素的先后位置,屬于穩定排序法,但插入排序的算法復雜度高。具體步驟如練習4-8所示。
【練習4-8】
將數組score賦值為{75,69,89,72,99,86,93,88,84,77},通過插入排序法將數組成員按從小到大的順序排序,代碼如下:
int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }; int[] score0 = new int[10]; score0[0] = score[0]; int num = 0; for (int i = 1; i < 10; i++) { num = score[i]; if(num>score0[i-1]) { score0[i] = num;} for (int j = 0; j < i; j++) { if (score0[j] > num) { for (int k = (i - 1); k >= j; k--) { score0[k + 1] = score0[k]; } score0[j] = num; break; } } } foreach (int sco in score0) { Console.Write("{0} ", sco); }
練習4-8中先將原數組第一個元素賦給新數組,這樣新數組可以視為只有一個元素的有序數組。將原數組的第二個元素與新數組中第一個元素比較后插入,新數組將有兩個元素,直到原數組最后一個元素的插入。
在插入時首先判斷插入元素是否比有序數組最后一個元素大,若插入元素最大,則直接放在有序數組最后,否則將依次跟有序數組元素相比較,找到合適的位置,將原有元素移位后,插入新元素。
4.2.5 刪除數組元素
數組元素的刪除相對容易,只需找到需要刪除的元素的位置,并將該元素之后的元素移位即可。
數組元素的刪除有兩種:一種是根據元素的索引刪除;另一種是在不知道索引的情況下,刪除有著某個值的元素。
1. 根據索引刪除元素
根據索引刪除數組元素,其實質是:將該索引后面的成員依次前移,覆蓋掉原有數據;最后將最后一個索引成員賦值為0(整型數組元素默認值為0)。由于數組的長度是不能變化的,因此成員的刪除,只是將后面的成員移位。
【練習4-9】
有數組score {75,69,89,72,99,86,93,88,84,77},將數組中的第3個元素刪除,使用代碼如下:
int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }; int del=3; //刪除第del個元素 for (int i = del; i < 10;i++ ) { score[i - 1] = score[i]; if (i == 9) { score[i] = 0; } } foreach (int sco in score) { Console.Write("{0} ", sco); }
執行結果為:
75 69 72 99 86 93 88 84 77 0
2. 刪除指定元素值
刪除指定元素值,需要先找出指定元素的位置再進行刪除,或直接將原有數組改為不含刪除元素值的新數組。
對于沒有重復元素的數組,可以找出要刪除的元素位置再刪除,如練習4-10所示。
【練習4-10】
有數組score {75,69,89,72,99,86,93,88,84,77},將數組中元素值為88的元素刪除,使用代碼如下:
int[] score = { 75, 69, 89, 72, 99, 86, 93, 88, 84, 77 }; int delnum=88; //要刪除的元素值 int del=0; for (int i = 0; i < 10; i++) { if (score[i] == delnum) { del = i; break; } } for (int i =( del+1) ; i < 10; i++) { score[i-1] = score[i]; if (i == 9) { score[i] = 0; } } foreach (int sco in score) { Console.Write("{0} ", sco); }
執行結果為:
75 69 89 72 99 86 93 84 77 0
若有重復的元素值,即使找出了元素位置,也不容易刪除。可以將原數組為新數組賦值,遇到要刪除的元素取消賦值并跳出。但這樣產生的結果是,需要被刪除的元素位置的值,被0取代。如練習4-11所示。
【練習4-11】
有數組score {75,69,89,74,99,86,93,74,84,77},將數組中元素值為74的元素刪除,使用代碼如下:
int[] score = { 75, 69, 89, 74, 99, 86, 93, 74, 84, 77 }; int delnum = 74; int[] score0 = new int[10]; for (int i = 0; i < 10; i++) { if (score[i] == delnum) { continue; } score0[i] = score[i]; } foreach (int sco in score0) { Console.Write("{0} ", sco); }
執行結果為:
75 69 89 0 99 86 93 0 84 77
- Effective C#:改善C#代碼的50個有效方法(原書第3版)
- Learning Chef
- 物聯網系統開發:從0到1構建IoT平臺(第2版)
- 算法精粹:經典計算機科學問題的Python實現
- VMware vSphere 6.7虛擬化架構實戰指南
- 新編Premiere Pro CC從入門到精通
- C語言實驗指導及習題解析
- Java程序設計
- Learning Salesforce Einstein
- 計算機應用基礎教程(Windows 7+Office 2010)
- 監控的藝術:云原生時代的監控框架
- Laravel Design Patterns and Best Practices
- 從“1”開始3D編程
- Python編程入門(第3版)
- 從零開始學算法:基于Python