Microsoft PowerPoint - SE7ch05.ppt

Similar documents
第1章

0 0 = 1 0 = 0 1 = = 1 1 = 0 0 = 1

2. 參考網站 C 語言考古題 & C 的解題 程式設計學習入門 ( 網址 : c.blogspot.com/) 網站 : 星子 ACM 小窩 ( 網址 : 網站 :ACM Onli

Microsoft Word - Prog1-981.docx

CHAPTER VC#

Microsoft PowerPoint - 12 struct and other datatypes.ppt

untitled

Microsoft PowerPoint - java2012-ch12投影片.ppt

Microsoft PowerPoint - C-Ch10.ppt

新・解きながら学ぶJava

untitled

Microsoft Word - JAVA Programming Language Homework I ans

Microsoft PowerPoint - C-Ch11.ppt

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new

Microsoft Word - ACL chapter02-5ed.docx

Microsoft Word - CS-981.doc

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

第1章

内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌

Microsoft Word - 第3章.doc

星星排列 _for loop Protected Sub Page_Load(ByVal sender As Object, ByVal e As Dim h As Integer = 7 'h 為變數 ' Dim i, j As Integer For i = 1 To h

Microsoft PowerPoint - EmbSys102_JavaOOP [相容模式]

Microsoft PowerPoint - ch04_AEL0080.ppt

CC213

untitled


Microsoft PowerPoint - 20-string-s.pptx

Microsoft PowerPoint - C_Structure.ppt

Microsoft PowerPoint - 04-array_pointer.ppt

Microsoft PowerPoint - STU_C_Lang_CH13.ppt

全國各級農會第 2 次聘任職員統一考試試題 科目 : 程式設計類別 : 九職等以下新進人員作答注意事項 : 1 全部答案請寫在答案卷內, 如寫在試題紙上, 則不予計分 2 請以黑色或藍色鋼筆或原子筆書寫, 並以橫式書寫 ( 由左至右, 由上而下 ) 一 選擇題 ( 每題 4 分, 共 40 分 )

第1章

ACI pdf

Microsoft PowerPoint - Class5.pptx

untitled

Microsoft PowerPoint - 第10章.ppt



jQuery實戰手冊

第3章.doc

Microsoft PowerPoint - vb_net8

p-2

本章內容 2-1 陣列及陣列位址的計算一維陣列位址計算多維陣列位址計算 2-2 一維陣列的基本運算讀取 寫入 複製 輸出 插入資料 刪除 2-3 二維陣列及矩陣的儲存與運算矩陣輸出 矩陣轉置 矩陣相加 矩陣相乘 2-4 字串 ( 字元陣列 ) 計算字串長度 字串複製 字串比較 子字串擷取 2

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

10-2 SCJP SCJD 10.1 昇陽認證 Java 系統開發工程師 的認證程序 Java IT SCJD

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

Java 程式設計初階 第 5 章:基本輸出入 & 流程控制

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

Microsoft PowerPoint - 13_指標、資料傳遞2.pptx

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

Microsoft Word - part doc

840 提示 Excel - Excel -- Excel (=) Excel ch0.xlsx H5 =D5+E5+F5+G5 (=) = - Excel 00

JavaIO.PDF

Microsoft PowerPoint - B9-2.pptx

Microsoft PowerPoint - SE7ch06.ppt

Excel VBA Excel Visual Basic for Application

(1) (2) (3) 1. (1) 2

EJB-Programming-4-cn.doc

01 用 ActionScript 3.0 開始認識 Flash CS3 Flash 是應用在網路上非常流行且高互動性的多媒體技術, 由於擁有向量圖像體積小的優點, 而且 Flash Player 也很小巧精緻, 很快的有趣的 Flash 動畫透過設計師的創意紅遍了整個網際網路 雖然很多人都對 Fl

jQuery實戰手冊

Microsoft PowerPoint - CH07 Arrays and Vectors [相容模式]

chp6.ppt

Microsoft PowerPoint - The Twelve Days of Xmas.ppt

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

Microsoft PowerPoint - SE7ch07.ppt

Microsoft PowerPoint - Bronson-v3-ch07.ppt [相容模式]

Microsoft PowerPoint - java2012-ch13投影片.ppt

任務二 : 產生 20 個有炸彈的磚塊, 放在隨機的位置編輯 Block 類別的程式碼 import greenfoot.; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) Write a description of class

javaexample-02.pdf

Chapter 9: Objects and Classes

Java 程式設計初階 第 5 章:基本輸出入 & 流程控制

Microsoft Word - C-pgm-ws2010.doc

<4D F736F F D203938BEC7ACECBCD2C0C0B8D5A8F7AEE6A6A1C0C92DB57BA6A1B35DAD705FA6B3B8D1B5AA5F2E646F63>

Microsoft Word - CPMidTerm2011SpringSolution

Powerpoint 2003

重 要 声 明 长 城 证 券 股 份 有 限 公 司 编 制 本 报 告 的 内 容 及 信 息 来 源 于 陕 西 东 岭 工 贸 集 团 股 份 有 限 公 司 提 供 的 证 明 文 件 以 及 第 三 方 中 介 机 构 出 具 的 专 业 意 见 长 城 证 券 对 报 告 中 所 包

C/C++基礎程式設計班

Microsoft PowerPoint - 04_Array

Transcription:

第五章陣列 課前指引陣列是一種非常重要的資料結構, 它可以讓程式設計更精簡 Java 也支援陣列, 但 Java 的陣列與早期程式語言 ( 如 C/C++) 的陣列有些不同 Java 的陣列可透過某些方法或屬性進行更多的應用 本章將針對陣列的原理及應用做深入且詳細的說明 章節大綱 5.1 一般程式語言的陣列概觀 5.2 Java 的陣列 5.4 其他類別對於陣列的可用方法 5.5 本章回顧 5.3 二維陣列 備註 : 可依進度點選小節

5.1 一般程式語言的陣列概觀 陣列是一種非常重要的資料結構, 幾乎各種高階程式語言都提供了陣列 什麼是陣列呢? 簡單來說, 陣列是一種儲存大量同性質資料的良好環境由於不必使用不同的變數名稱, 以及陣列元素存取的方便性, 使得大多數的程式設計中, 都看得到陣列的影子 3 5.1 一般程式語言的陣列概觀 陣列 是一群資料型態相同的變數, 並且在記憶體中會以連續空間來加以存放 舉例來說, 假設我們想要記錄每月的營業額, 您當然可以使用 January February December 等 12 個數值變數來儲存這些資料, 但如果您使用的是陣列來儲存的話, 則可以只使用同一個陣列變數名稱即可, 例如 :Month [] 並將 Month[0]~Month[11] 對應於各月之營業額 for(int i=0;i<=11;i++) Sum=Sum+Month[i]; 4

5.1 一般程式語言的陣列概觀 在上面的小範例中, 我們可以發現陣列中的每個元件 ( 陣列元素 ) 相當於一個變數, 我們只要透過索引 (index), 就可以直接取得陣列的指定元素 (Java 的陣列索引由 0 開始計算 ) 因此, 使用陣列可以免除大量變數命名的問題, 使得程式具有較高的可讀性 一般程式語言都提供了上述的陣列資料結構, 不過索引起始值則可能有所不同 5 5.2 Java 的陣列 在 Java 中, 陣列以變數名稱來表示, 要使用陣列之前, 首先您必須決定該陣列的元素為何種資料型態, 以及該陣列的名稱 決定這兩種資料之後, 您可以透過下列語法來宣告一個陣列變數 : 宣告陣列名稱 語法 : 資料型態陣列名稱 [ ]; 或資料型態 [ ] 陣列名稱 ; 功能 : 宣告 Java 的一維陣列, 以及陣列元素資料型態 6

5.2 Java 的陣列 語法說明 : (1) 資料型態 : 陣列的資料型態可以是原始資料型態, 也可以是某種類別 ( 非原始資料型態 ), 例如 :int,float,,string 等等 (2) 陣列名稱 : 陣列名稱的命名規定與變數命名規定相同, 您應該盡量採用有意義的英文字或組合字來代表該陣列的用途 範例 : 假設我們有學生的成績或學生的學號需要記錄 則可以將陣列宣告為 stuscore 或 stuid, 如下宣告 ( 一維 ) 陣列 : int stuscore[]; String stuid[]; // 可改寫為 int[] stuscore; // 可改寫為 String[] stuid; 7 5.2 Java 的陣列 產生陣列實體 當我們有了陣列名稱後, 應該要為該陣列配置陣列元素所需要的記憶體空間, 它可以透過下列語法來實現 : 語法 : 陣列名稱 = new 資料型態 [ 元素個數 ]; 功能 : 為陣列配置實體的記憶體空間 8

5.2 Java 的陣列 語法說明 : (1) 資料型態 : 此處的資料型態必須與宣告陣列名稱時的資料型態相同 (2) 元素個數 : 所需要的陣列元素個數, 它必須是一個整數變數或常數 ( 一般為常數 ), 並且不能是 long 型態 例如要記載 12 個月份的營業額, 則此處可宣告為 12 (3) 陣列產生實體後, 就可以透過索引存取陣列元素, 語法如下 語法 : 陣列名稱 [ 索引值 ] 功能 : 存取陣列元素 說明 : 在 Java 中, 陣列第一個元素的索引值為 0, 第二個元素的索引值為 1, 依此類推, 所以長度為 n 的陣列, 其索引值為 0~n-1 9 5.2 Java 的陣列 範例 : 假設學生共有 5 位, 則可以如下宣告 ( 一維 ) 陣列並配置實體 : int stuscore[]; // 可改寫為 int[] stuscore; stuscore = new int[5]; // 配置記憶體空間 stuscore[3] = 84; // 設定陣列第四個元素為 84 String stuid[]; // 可改寫為 String[] stuid; stuid = new String[5];// 請配置五個元素記憶體空間 10

5.2 Java 的陣列 宣告陣列名稱並產生陣列實體 上述的語法可以合併, 也就是在宣告敘述時, 一併完成陣列元素的記憶體配置 語法 : 資料型態陣列名稱 [ ] = new 資料型態 [ 元素個數 ]; 或資料型態 [ ] 陣列名稱 = new 資料型態 [ 元素個數 ]; 功能 : 宣告陣列名稱並配置陣列元素的記憶體空間 範例 上述範例可以改寫如下 : int[] stuscore=new int[5]; String[] stuid=new String[5]; 11 5.2 Java 的陣列 說明 : 當您完成上述的宣告與記憶體配置之後, 就可以開始存取記憶體元素, 例如 stuscore[3]=84 ( 結果如圖 5-1) 不過, 陣列資料型態若為類別 ( 非原始資料型態 ), 則代表陣列元素為物件名稱, 您仍必須對物件進行實體的配置動作 ( 也就是產生物件實體 ) 圖 5-1 陣列在記憶體中的示意圖 ( 記憶體位址為假設值 ) 12

5.2.1 宣告陣列的實際行為 雖然宣告陣列與配置陣列實體的語法很簡單, 但事實上, 它隱含了一些特殊的記憶體配置動作 以 int stuscore[]=new int[5]; 為例, 它事實上可以分解為下列三項動作 : Step1:int stuscore[]: 在記憶體中預留一個足以記錄記憶體位址的空間 Step2:new int[5]: 配置 5 個連續的 int 整數空間以作為陣列之元素存放之處, 並在其後留下部分記憶體, 記錄陣列可用之屬性及相關方法 (Step1 與 Step 2 如下圖所示 ) 13 5.2.1 宣告陣列的實際行為 Step3: = : 將陣列實體的起始位置填入 Step1 的內容 14

5.2.1 宣告陣列的實際行為 說明 : (1) 由於陣列名稱事實上只是記錄陣列實體的初始位址, 因此我們將這樣的記錄方式稱為參考 (reference) 在 Java 中, 許多程式的背後都隱含著參考, 例如物件名稱事實上也是物件實體的參考 (2) 當 Step3 完成後, 我們就可以透過陣列名稱及索引方式取得陣列元素 (3)Java 的陣列與其他早期程式語言 ( 如 C/C++) 的陣列有一個很大的不同之處,Java 的陣列類似物件, 也提供了某些屬性與方法, 例如陣列長度 length clone 方法等 (4) 事實上, 當陣列配置完成後, 會進行陣列元素的初始化動作, 請見下一小節的說明 15 5.2.2 陣列的初始化 陣列元素如果未指定初始值, 則陣列元素在實體產生時, 會自動作初始化動作其中原始資料型態的陣列元素會被初始化為 0 或 0.0( 整數類或浮點數類 ) '\u0000'( 字元 ) false( 布林 ) 如果陣列元素是物件的參考, 則會被初始化為 null 除自動初始化之外, 我們也可以在宣告或產生陣列實體時, 設定陣列元素的初始內容, 語法如下 : 語法一 : 資料型態陣列名稱 [ ] = new 資料型態 [ ] 元素 1 初始值, 元素 2 初始值, ; 語法二 : 資料型態 [ ] 陣列名稱 = new 資料型態 [ ] 元素 1 初始值, 元素 2 初始值, ; 語法三 : 資料型態陣列名稱 [ ] = 元素 1 初始值, 元素 2 初始值, ; 語法四 : 資料型態 [ ] 陣列名稱 = 元素 1 初始值, 元素 2 初始值, ; 功能 : 初始化陣列元素 16

5.2.2 陣列的初始化 語法說明 : (1) 由於在指定初始值時, 編譯器可以確定陣列有幾個陣列元素, 因此不需要設定元素個數值 (2) 語法一及語法二可拆寫為兩行, 如下 : 語法一 : 資料型態陣列名稱 [ ]; 陣列名稱 = new 資料型態 [ ] 元素 1 初始值, 元素 2 初始值, ; 語法二 : 資料型態 [ ] 陣列名稱 ; 陣列名稱 = new 資料型態 [ ] 元素 1 初始值, 元素 2 初始值, ; 17 5.2.2 陣列的初始化 陣列的初始化範例 : int Ary1[] = new int[]5,3,6,1; int[] Ary2 = new int[]3,2,7,4,9; int Ary3[]; Ary3 = new int[]4,3,2,2; int[] Ary4; Ary4=new int[]3,3,5,2 int Ary1[]=5,3,6,1; int[] Ary2=3,2,7,4,9; // 語法一 // 語法二 // 語法一 // 語法二 // 語法三 // 語法四 18

5.2.2 陣列的初始化 如果陣列元素是物件參考時, 則您也可以於陣列實體配置時, 將物件生成直接加入其中, 使得物件參考得以直接指向物件實體位址, 其語法如下 : 語法一 : 資料型態陣列名稱 [ ] = new 資料型態 [ ]new 建構子 ( 引數列 ),new 建構子 ( 引數列 ), ; 語法二 : 資料型態陣列名稱 [ ] = new 建構子 ( 引數列 ),new 建構子 ( 引數列 ), ; 19 5.2.2 陣列的初始化 語法說明 : 我們省略了之前其他各種變形的語法, 實際上這些語法也可以 其中建構子與物件的類別名稱相同 範例 : String Ary[] = new String[]new String("abc"), new String("Hello"); 說明 : Ary 是一個字串陣列, 陣列元素 Ary[0],Ary[1] 為字串變數 ( 物件參考 ), 由於設定了初始值, 因此, 這兩個字串物件變數將參考到字串實體 "abc" 與 "Hello" 意即 System.out.print(Ary[1]); 敘述會印出 Hello 字串 20

5.2.3 陣列的長度 之前提及,Java 的陣列與物件極為類似, 也提供了一些屬性 (Fields) 與方法 (Methods) 其中, 最常被使用的應該是 length 屬性與 clone 方法陣列長度有時候是很有用的, 例如當我們想要計算陣列元素的總和時, 可以透過下列片段程式來完成 int Month[]=new int[]10,20,15,29,40,42,76,98,34,13,17,25; int Sum=0; for(int i=0;i < Month.length;i++) Sum=Sum+Month[i]; 21 5.2.4 共用陣列與複製陣列 Java 的陣列名稱只是一個參考 如果我們將兩個陣列名稱的 參考對象 都設定為同一個陣列實體, 則兩個陣列將可以 共用 同一個陣列內容 如下範例 : 22

5.2.4 共用陣列與複製陣列 int Month[]=new int[]10,20,15,29,40,42,76,98,34,13,17,25; int Trade[]; Trade=Month; // Trade 參考至 Month 參考的陣列實體 Trade[2]=50; System.out.print(Month[2]); 說明 : 上述片段程式會印出 50, 因為兩個陣列變數參考到同一個陣列實體, 右圖是其示意圖 23 5.2.4 共用陣列與複製陣列 如果 Trade 只是想要和 Month 陣列相同, 但不想因為修改其元素值而影響了 Month 陣列, 則應該先使用 clone 將 Month 陣列的實體內容複製一份, 然後再將 Trade 參考指向複製的陣列實體, 如下範例 : int Month[]=new int[]10,20,15,29,40,42,76,98,34,13,17,25; int Trade[]; Trade=Month.clone(); //clone 會複製一份陣列實體, 並回傳複製的陣列實體之初始位址 Trade[2]=50; System.out.println(Month[2]); System.out.println(Trade[2]); 24

5.2.4 共用陣列與複製陣列 說明 : 上述片段程式會印出 15 與 50 兩個值, 因為兩個陣列變數參考到不同的陣列實體, 下面是其示意圖 25 5.2.4 共用陣列與複製陣列 我們可以將 Month 陣列的實體參考設定給 Trade 陣列變數, 即使 Trade 原本已經指向其他陣列實體, 如下範例 : int Month[]=new int[]10,20,15,29,40,42,76,98,34,13,17,25; int Trade[]=new int[]20,18,87,65; System.out.println(Trade.length); Trade=Month; // Trade 參考至 Month 參考的陣列實體 System.out.println(Trade.length); 說明 : 上述範例會印出 4 與 12 兩個數值, 看似陣列長度被改變了, 但其實陣列實體的長度並沒有改變, 而是因為參考的陣列實體不同所導致 26

5.2.4 共用陣列與複製陣列 共用陣列與複製陣列 實用範例 5-1 : 使用陣列存放營業額, 並計算年度營業額與各月平均營業額 範例 5-1:ch5_01.java( 隨書光碟 myjava\ch05\ch5_01.java) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /* 檔名 :ch5_01.java 功能 : 陣列元素的存取 */ package myjava.ch05; import java.lang.*; import java.io.console; public class ch5_01 // 主類別 public static void main(string args[]) int sum=0; double average; Console console=system.console(); 27 5.2.4 共用陣列與複製陣列 15 16 17 18 19 20 21 22 23 24 25 26 27 int trade[]=new int[4]; // 宣告 trade 陣列並產生陣列實體 for(int i=0;i<trade.length;i++) System.out.print(" 第 " + (i+1) + " 季的營業額 :"); trade[i] = Integer.parseInt(console.readLine()); sum = sum + trade[i]; average=(double)sum/(double)12; System.out.println("========================="); System.out.println(" 年度營業額 :" + sum); System.out.println(" 平均各月營業額 :" + average); 執行結果 : 第 1 季的營業額 :63328 第 2 季的營業額 :58723 第 3 季的營業額 :78321 第 4 季的營業額 :65551 ========================= 年度營業額 :265923 平均各月營業額 :22160.25 28

5.2.4 共用陣列與複製陣列 範例說明 : 使用迴圈將輸入的各季營業額逐一存入 trade 陣列的 trade[i] 元素中, 並且累加營業額總和 最後計算各月平均營業額 29 5.2.5 氣泡排序法 (Bubble Sort) 補充 搜尋與排序是程式設計的一項基本且重要的問題 所謂 搜尋 (Searching), 指的是在一堆資料中, 尋找您所想要的資料, 例如 : 在英文字典中找尋某一個單字 所謂 排序 (Sorting) 則是將一堆雜亂的資料, 依照某個鍵值 (Key Value) 依序排列, 方便日後的查詢或使用 例如 : 英文字典中每個單字就是已經排序後的結果 從 a~z 30

5.2.5 氣泡排序法 (Bubble Sort) 補充 相信讀者都有搜尋與排序資料的經驗, 以搜尋英文字典為例, 您或許有自己的一套方法找到所需要的單字例如 : 查單字 good, 您可能會先翻閱字典的前 1/3, 看看該頁中的單字字首是哪一個英文字母, 然後再略為調整頁數, 直到找到資料為止 而在電子字典中, 您只需要輸入 good, 然後電腦或翻譯機就會自動幫您找到 good 這個單字的相關資訊, 問題是電腦是如何幫您找到這個單字的呢? 這就是研究 搜尋 演算法所關心的議題了 31 5.2.5 氣泡排序法 (Bubble Sort) 補充 電腦的許多基礎科學是從數學衍生而來 因此, 即使在個人電腦還不普及的年代, 早就有很多專家們對此一問題發展出許多的解決方法 例如 : 排序 問題的解決方法就有很多種, 其難度與效率也各自不同, 您可以在資料結構或演算法的課程中, 學習到這些知識 在這裡, 我們先補充比較簡單的 氣泡排序法 一般我們會將欲排序的資料存放於陣列中, 所以接下來, 我們將介紹的 氣泡排序 演算法的作用目標將是陣列資料結構 32

5.2.5 氣泡排序法 (Bubble Sort) 補充 氣泡排序法 是一種非常簡單且容易的排序方法 ( 當然效率表現也僅僅算是普通而已 ), 簡單地來說, 氣泡排序法 是將相鄰兩個資料一一互相比較, 依據比較結果, 決定資料是否需要對調, 由於整個執行過程, 有如氣泡逐漸浮上水面, 因而得名, 其方法及示意圖如下 : 假設我們有 24,7,36,2,65 要做氣泡排序, 最後的排序結果為 2,7,24,36,65 33 5.2.5 氣泡排序法 (Bubble Sort) 補充 演算法 ( 使用非正式但較接近 Java 語法的虛擬碼 ) 輸入 : 未排序的資料 x[0]~x[n-1] 輸出 : 已排序的資料 k n-1; while(k!=0) t 0; for(i=0 ; i<=k-1 ; i++) if(x[i] > x[i+1]) x[i] x[i+1]; t i; endif endfor k t; endwhile //x[i] 與 x[i+1] 互換 34

5.2.5 氣泡排序法 (Bubble Sort) 補充 實例說明 : 若陣列的五個元素資料 A[0],A[1],A[2],A[3],A[4] 要由小到大排序, 則以下是詳細步驟 : 第一回合 : 相鄰兩個資料相互比較, 依照下列步驟, 最大值將被放入 A[4] 中 : A[0] 和 A[1] 比較, 若 A[0]>A[1] 則資料互換, 否則資料不交換 A[1] 和 A[2] 比較, 若 A[1]>A[2] 則資料互換, 否則資料不交換 A[2] 和 A[3] 比較, 若 A[2]>A[3] 則資料互換, 否則資料不交換 A[3] 和 A[4] 比較, 若 A[3]>A[4] 則資料互換, 否則資料不交換 很容易可以發現, 經過上面四次比較之後, 最大的資料一定會被放到 A[4] 之中, 如此稱為 第一回合掃描 35 5.2.5 氣泡排序法 (Bubble Sort) 補充 第二回合 : 由於在第一回合時,A[0]~A[4] 的最大值已經被放到 A[4] 了, 因此在第二次回合掃描時, 只需要仿照第一回合, 將 A[0]~A[3] 中最大的值放到 A[3] 中即可 ( 明顯地, 第二回合掃描只需要比較 3 次 ) 第三回合 : 由於在第一 二回合時,A[0]~A[4] 的最大值及第二大值已經被放到 A[4] A[3] 了, 因此在第三回合掃描時, 只需要仿照第一回合, 將 A[0]~A[2] 中最大的值放到 A[2] 中即可 ( 明顯地, 第三回合掃描只需要比較 2 次 ) 36

5.2.5 氣泡排序法 (Bubble Sort) 補充 第四回合 : 由於在第一 二 三回合時,A[0]~A[4] 的最大值 第二大值 第三大值已經被放到 A[4] A[3] A[2] 了, 因此在第四次回合掃描時, 只需要仿照第一回合, 將 A[0]~A[1] 中最大的值放到 A[1] 中即可 ( 明顯地, 第四回合掃描只需要比較 1 次 ) 第五回合 : 最後剩下 A[0], 不必比較就知道 A[0] 中的值是最小的值 ( 第五回合可省略 ) 所以五筆資料使用氣泡排序, 需要經過四個回合的掃描, 一共比較 (4+3+2+1)=10 次 以此類推,N 筆資料做氣泡排序, 需要 (N-1) 次掃描, 共比較 (N-1)+(N-2)+(N-3)+ +3+2+1 = N(N-1)/2 次 另外, 在排序過程中, 若有某一回合的掃描沒有交換任何的資料, 則代表資料已經提早排序完成, 此時可略過後面尚未掃描的回合 因此 N(N-1)/2 次比較是最差的狀況 37 5.2.5 氣泡排序法 (Bubble Sort) 補充 小試身手 5 1 上述的氣泡排序, 當有 N 筆資料進行排序時, 在最佳狀況下, 需要做幾次比較? 實用範例 5-2 : 使用氣泡排序法, 將樂透的 6 個號碼依據數字大小排序顯示 ( 特別號除外 ) 範例 5-2:ch5_02.java( 隨書光碟 myjava\ch05\ch5_02.java) 38

5.2.5 氣泡排序法 (Bubble Sort) 補充 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /* 檔名 :ch5_02.java 功能 : 陣列與排序 */ package myjava.ch05; import java.lang.*; public class ch5_02 public static void main(string args[]) int x[]=25,10,39,40,33,12; int spec=11; int k,times,temp; 執行結果 10 12 25 33 39 40 特別號 11 k=x.length-1; //x.length=6, 代表 6 球 while(k!=0) times=0; for(int i=0;i<=k-1;i++) if(x[i]>x[i+1]) temp=x[i]; x[i]=x[i+1]; x[i+1]=temp; // x[i] times=i; k=times; 宣告一維陣列用來儲存樂透開獎號碼, 並設定陣列元素初始值, 即尚未排序的 6 個樂透開獎號碼 x[i+1] 39 5.2.5 氣泡排序法 (Bubble Sort) 補充 28 29 30 31 32 印出排序後的結果 for(int i=0;i<6;i++) System.out.print(x[i]+ "\t"); System.out.println("\n 特別號 \t" + spec); 範例說明 : (1) 第 15~27 行 : 每一次執行 while 迴圈代表每一次回合的掃描 (2) 第 18~25 行 : 每一次執行 for 迴圈代表執行該回合掃描的比較 (3)times 用來控制下一回合掃描的比較次數遞減一次, 並且若這次掃描中沒有任何互換動作發生, 則不需要再掃描, 直接跳出 while 迴圈 (4) 第 28~30 行 : 印出排序後的結果 (5) 您可以在 26~27 行間插入 for(int j=0;j<6;j++) System.out.print(x[j]+ "\t"); 印出每次掃描後的結果 您也可以將陣列初始值改為 5,10,15,20,25,30, 並且插入這些程式碼, 然後看看會掃描幾次 40

5.3 二維陣列 陣列若具有兩個索引稱為 二維陣列 具有三個索引稱為 三維陣列, 依此類推 而二維陣列的使用十分廣泛 ( 僅次於一維陣列 ) 您可以將二維陣列以數學之矩陣來加以看待, 也就是二維陣列是由 列 ( Row) 與 行 (Column) 組合而成 每一個元素恰恰落在特定之某一列的某一行 首先, 我們先來釐清所謂的列與行的差別所謂 列, 指的是 橫列 而 行 指的是 直行 老師的叮嚀 若您對於列與行容易產生混淆的話, 可以利用一些小技巧來加以記憶 通常我們稱一列火車, 因此, 列 為橫列而國小的國語作業, 老師們不是都安排寫某個生字幾行嗎? 而國語作業簿是以直行來加以計算, 因此, 行 為直行 不過請注意, 第幾行程式的 行 指的是英文的 line; 而陣列第幾行的 行 則指的是英文的 Column, 兩者的意義是不同的 41 5.3 二維陣列 列 也就是二維陣列的第一維索引, 而 行 則是二維陣列的第二維索引 我們可以用二維陣列來表示複雜的資料倘若使用橫列來表示各分公司的營運狀況, 直行表示各季的營業額, 則可以如圖安排整間公司的總體營運狀況 第一季 第二季 第三季 第四季 台北總公司 ( 第 1 列 ) trade[0][0] trade[0][1] trade[0][2] trade[0][3] 新竹園區 ( 第 2 列 ) trade[1][0] trade[1][1] trade[1][2] trade[1][3] 高雄分公司 ( 第 3 列 ) trade[2][0] trade[2][1] trade[2][2] trade[2][3] 42

5.3 二維陣列 在上面的營運業績範例,trade [3][4] 陣列共有 3 列 4 行, 包含 (3*4)=12 個元素若要取得高雄分公司第 3 季的營業額, 則應該以相對應的索引值來加以取得, 也就是 trade [2][2] ( 在 Java 中, 二維陣列的行列索引起始值仍是由 0 開始計算 ) 二維陣列可以使用表格或矩陣來加以示意, 三維陣列則需要使用三度空間圖形加以示意, 更多維度的陣列則無法使用幾何圖形來示意, 但存取方法也大同小異 建議讀者, 盡量使用 1~3 維陣列來儲存資料以上是一般程式語言對於二維陣列的支援, 但 Java 的二維陣列則並非如此單純甚至可以說 Java 並未直接提供二維陣列 43 5.3.1 Java 的二維陣列 Java 並沒有直接提供二維陣列, 對 Java 而言, 二維陣列是由兩層的一維陣列所構成, 意即每一個 列的陣列元素 存放的都是 代表一整行的一維陣列, 而陣列的陣列就可以構成二維陣列的效果 因此, 對於二維陣列的 length 屬性而言, 它只是記錄了有幾列而已, 而非二維陣列總共有幾個陣列元素 例如上述的 trade 二維陣列的示意圖如下 : 圖 5-3 Java 的二維陣列事實上是由兩層的一維陣列所構成 44

5.3.1 Java 的二維陣列 對於陣列 trade 而言 它的陣列長度 length 為 3, 包含三個陣列元素 ( 因為它有 3 列 ), 並且每個陣列元素也是一個一維陣列 對於陣列 trade[0] 或 trade[1] 或 trade[2] 而言, 它的陣列長度 length 為 4, 包含了四個陣列元素 ( 因為每一列有 4 行 ) 故一共有 12 個陣列元素 雖然 Java 的二維陣列是由兩層的一維陣列所組成, 但 Java 仍提供了快速宣告以及快速存取的語法以減少程式設計師撰寫程式的麻煩 45 5.3.2 二維陣列的簡易宣告語法 在 Java 中, 宣告二維陣列可以如同其他程式語言般的簡單, 其語法如下 : 宣告二維陣列名稱 語法 : 資料型態陣列名稱 [ ][ ]; 或資料型態 [ ][ ] 陣列名稱 ; 功能 : 宣告 Java 的二維陣列, 並指定第二維陣列元素的資料型態 說明 : 以上述的 trade 營業額範例來說, 假設營業額為整數, 則可以宣告陣列名稱如下 : int trade[][]; 或 int[][] trade; 46

5.3.2 二維陣列的簡易宣告語法 宣告陣列名稱並產生陣列實體如果您想要在宣告陣列名稱時, 同時配置陣列的實體, 則可使用如下語法 : 語法 : 資料型態陣列名稱 [][] = new 資料型態 [ 第一維元素個數 ][ 第二維元素個數 ]; 或資料型態 [][] 陣列名稱 = new 資料型態 [ 第一維元素個數 ][ 第二維元素個數 ]; 功能 : 宣告二維陣列名稱並配置陣列元素的記憶體空間 範例 : 以上述的 trade 營業額範例來說, 則可於宣告陣列名稱的同時, 配置陣列實體 : int trade[][] = new int[3][4]; 或 int[][] trade = new int[3][4]; 47 5.3.2 二維陣列的簡易宣告語法 說明 : 由於上述語法中, 並未設定 trade 元素的初始值, 因此會被自動初始化為 0, 故上述語法實際在記憶體中的配置如下圖 : 圖 5-4 Java 的二維陣列 ( 記憶體位址為假想值 ) 48

5.3.2 二維陣列的簡易宣告語法 實用範例 5-3 : 將九九乘法表的乘法結果儲存在 9 9 的二維整數陣列之中, 並將陣列的資料列印出來 範例 5-3:ch5_03.java( 隨書光碟 myjava\ch05\ch5_03.java) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /* 檔名 :ch5_03.java 功能 : 二維陣列的練習 */ package myjava.ch05; import java.lang.*; public class ch5_03 // 主類別 public static void main(string args[]) // 宣告二維陣列 m[9][9], 共有 81 個元素, 從 m[0][0]~m[8][8] int m[][]=new int[9][9]; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) m[i-1][j-1]=i*j; // 將九九乘法的結果存入二維陣列中 49 5.3.2 二維陣列的簡易宣告語法 16 17 18 19 20 21 22 23 24 for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) System.out.print(i + "*" + j + "=" + m[i-1][j-1] + "\t"); System.out.println(); 執行結果 :( 同範例 4-17) 範例說明 : 第 17~22 行是用來取出二維陣列的各個元素值 ( 內存放九九乘法表之結果 ),m[i-1][j-1] 放在雙層迴圈內, 恰好可取出 m[0][0]~m[8][8] 的元素值 迴圈與陣列常常搭配使用, 以精簡程式碼 50

5.3.2 二維陣列的簡易宣告語法 宣告二維陣列並設定初始值 在宣告二維陣列的同時, 也可以指定陣列元素的初始值 ( 和一維陣列類似 ), 語法如下 : 語法 : 資料型態陣列名稱 [ ][ ]= 第一列元素的初始值, 第二列元素的初始值, : : 最後一列元素的初始值 ; 功能 : 宣告二維陣列並設定陣列元素的初始值 語法說明 : (1) = 前面的 資料型態陣列名稱 [][] 可改寫為 資料型態 [][] 陣列名稱 51 5.3.2 二維陣列的簡易宣告語法 語法說明 : (2) 每一列可能包含眾多元素, 其中以, 加以區隔 如下範例 : int score[][]=85,78,65, 75,85,69, 63,67,95, 94,92,88, 74,65,73 ; //score 是一個 5 3 的二維陣列, 其中 score[3][1] 的元素值為 92 52

5.3.2 二維陣列的簡易宣告語法 語法說明 : (3) 在語法中, 我們可以發現到, 它並未要求每一列的元素個數必須相同, 例如下列範例可以設定一個 列長度不同 的二維陣列, 這是因為 Java 的二維陣列事實上是由兩層的一維陣列所構成 int score[ ][ ]=85,78,65, 75, 63,95, 94,92,88; /* score 是一個二維陣列, 其中第 0 列有 3 個元素, 第 1 列有 1 個元素, 第 2 列有 2 個元素, 第 3 列有 3 個元素 */ 53 5.3.2 二維陣列的簡易宣告語法 觀念範例 5-4 : 使用二維陣列存放學生的期中考成績 範例 5-4:ch5_04.java( 隨書光碟 myjava\ch05\ch5_04.java) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /* 檔名 :ch5_04.java 功能 : 二維陣列的練習 */ package myjava.ch05; import java.lang.*; public class ch5_04 // 主類別 public static void main(string args[]) double score[][] = 85,78,65,0, 75,85,69,0, 63,67,95,0, 94,92,88,0, 74,65,73,0; System.out.println(" 計概 \t 數學 \t 英文 \t 平均 "); System.out.println("=============================="); 54

5.3.2 二維陣列的簡易宣告語法 18 19 20 21 22 23 24 25 26 for(int i=0;i<5;i++) score[i][3] = (score[i][0]+score[i][1]+score[i][2])/3; for(int j=0;j<4;j++) System.out.print(score[i][j] + "\t"); System.out.println(); 執行結果 : 計概 數學 英文 平均 ============================== 85.0 78.0 65.0 76.0 75.0 85.0 69.0 76.33333333333333 63.0 67.0 95.0 75.0 94.0 92.0 88.0 91.33333333333333 74.0 65.0 73.0 70.66666666666667 55 5.3.2 二維陣列的簡易宣告語法 範例說明 : 陣列中每一列代表一個學生的成績, 所以共有 5 位學生的成績 每一列的第 4 個元素 ( 即 score[i][3]) 是用來存放該列的平均分數 56

5.3.3 二維陣列的分段宣告 在上一小節中, 我們透過設定初值方式, 完成了一個列長度不同的二維陣列宣告, 如果不想手動設定初值, 是否也可以完成列長度不同的二維陣列呢? 答案是可以的, 但必須將 宣告陣列名稱 與 產生陣列實體 分段完成, 並且這個方法也可以應用於列長度相等的二維陣列宣告 要進行二維陣列的分段宣告首先必須先宣告二維陣列名稱, 其如同前面的語法, 接著在產生陣列實體時, 我們只先產生列的實體 ( 先不產生行陣列元素的實體 ), 如下語法 : 語法 : 資料型態陣列名稱 [ ][ ]; // 或資料型態 [ ][ ] 陣列名稱 ; 陣列名稱 = new 資料型態 [ 第一維元素個數 ][ ]; 功能 : 宣告 Java 的二維陣列, 並產生第一維的實體 57 5.3.3 二維陣列的分段宣告 說明 : 兩行可合併為如下語法 : 語法 : 資料型態陣列名稱 [ ][ ]= new 資料型態 [ 第一維元素個數 ][ ]; 舉例來說, 假設我們想要宣告的是具有 3 列的 trade 二維整數陣列, 則可如下宣告 : int trade[][]; trade = new int[3][]; 兩行可合併如下 : int trade[][] = new int[3][]; 58

5.3.3 二維陣列的分段宣告 有了第一維的實體之後, 我們可以為每一個列產生第二維的實體, 假設每一列的元數個數相同, 則可套用如下語法 : 語法 :for(int i=0;i< 陣列名稱.length.i++) 陣列名稱 [i] = new 資料型態 [ 第二維元素個數 ]; 功能 : 產生二維陣列第二維的實體 59 5.3.3 二維陣列的分段宣告 舉例來說, 假設我們想要宣告的是 3 4 的 trade 二維整數陣列, 則可如下宣告 : int trade[][]; trade = new int[3][]; for(int i=0;i<trade.length;i++) trade[i]=new int[4]; 說明 : 迴圈中, 使用了 trade.length 作為迴圈執行次數, 此處的 length 是代表列的數量, 故為 3, 因此迴圈內的敘述實際上如下, 經由這樣的宣告後, 我們就可以正常透過列與行的索引來存取陣列元素了 trade[0]=new int[4]; trade[1]=new int[4]; trade[2]=new int[4]; 60

5.3.3 二維陣列的分段宣告 仔細觀察上述範例, 我們可以發現, 如果不要使用迴圈, 而是分別對於每一列進行第二維的實體宣告, 則可以達成不同列長度的二維陣列宣告, 如下範例 : int trade[][] = new int[3][]; // 二維陣列有 3 列 trade[0]=new int[4]; // 第 0 列有 4 個元素 trade[1]=new int[2]; // 第 1 列有 2 個元素 trade[2]=new int[3]; // 第 2 列有 3 個元素 Coding 偷撇步 由於 Java 是以兩層一維陣列方式實現二維陣列, 因此在分段宣告時較為複雜, 這樣的方式到了三維以上的陣列時, 將更複雜 因此, 建議盡量少用三維以上的陣列, 或三維以上陣列盡量採用簡易的宣告方式 61 5.3.4 複製部分陣列 陣列本身擁有 clone 方法可進行陣列實體的複製, 即使是多維陣列, 也可以透過 clone 方法複製整個陣列的實體, 其語法是 陣列名稱.clone() 而如果我們只想要複製多維陣列中的某一維陣列, 也是可以透過 clone 方法完成的, 因為, 每一維都有一個陣列參考可執行 clone 方法 請見以下的範例 觀念範例 5-5 : 使用 clone 複製部分陣列 範例 5-5:ch5_05.java( 隨書光碟 myjava\ch05\ch5_05.java) 62

5.3.4 複製部分陣列 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /* 檔名 :ch5_05.java 功能 : 複製部分陣列 */ package myjava.ch05; import java.lang.*; public class ch5_05 // 主類別 public static void main(string args[]) int score[][]=85,78,65, 75, 63,95, 94,92,88; int ary[]; ary=score[3].clone(); for(int i=0;i<ary.length;i++) System.out.print(ary[i] + "\t"); 執行結果 94 92 88 範例說明 : 第 15 行是將 score[3] 的一維陣列複製給 ary, 由於陣列的某一維長度可能不一, 故通常配合 length 存取陣列元素, 否則可能因為存取到不存在的陣列元素 ( 例如 ary[5]) 而出現執行時期的錯誤 63 5.4 其他類別對於陣列的可用方法 對於 Java 而言, 除了原始資料型態 String 類別之外最常見的資料結構大概可說是 陣列, 因此,Java 的許多類別都提供了某些 static 方法可以對陣列進行操作 在本節中, 我們以兩個範例來說明之後讀者若在 Java 的說明文件中, 看到參數為陣列型態, 都可以按照其說明進行應用 64

5.4.1 複製陣列部分元素 : System.arraycopy() arraycopy 是 System 類別的一個 static 方法 它可以複製陣列的某段元素值, 設定給另一個陣列的某段元素 ( 起始索引不需要相同 ), 其方法的宣告原型如下 : 語法 :public static void arraycopy(object src, int srcpos, Object dest, int destpos, int length) 所屬類別 :java.lang.system 功能 : 複製陣列部分元素 65 5.4.1 複製陣列部分元素 : System.arraycopy() 說明 : (1) 共有五個參數, 使用於陣列元素複製時,src 代表來源陣列,dest 代表目標陣列 srcpos 代表來源陣列複製起始索引,destPos 代表目標陣列複製起始索引, length 代表要複製幾個元素 (2) 來源陣列與目標陣列的資料型態必須相容, 如果是原始資料型態, 則必須完全一樣, 因為該 method 並不會幫您作自動轉型的動作 實用範例 5-6 : 使用 System.arraycopy() 複製字元陣列的某些字元 範例 5-6:ch5_06.java( 隨書光碟 myjava\ch05\ch5_06.java) 66

5.4.1 複製陣列部分元素 : System.arraycopy() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /* 檔名 :ch5_06.java 功能 : 複製部分陣列 */ package myjava.ch05; import java.lang.*; public class ch5_06 // 主類別 執行結果 Hello Java! public static void main(string args[]) char[] ary1='t','h','e','j','a','v','a','2'; char[] ary2='h','e','l','l','o',' ','T','i','m','e','!'; System.arraycopy(ary1,3,ary2,6,4); for(int i=0;i<ary2.length;i++) System.out.print(ary2[i]); 67 5.4.1 複製陣列部分元素 : System.arraycopy() 範例說明 : 第 13 行將會複製 ary1[3]~ary1[3+4-1] 到 ary2[6]~ary2[6+4-1], 而原本 ary2[6] ~ ary2[6+4-1] 的資料將被覆蓋, 其餘則不變 示意圖如下 : 68

5.4.2 對陣列排序 :Arrays.sort() Arrays 類別的 sort 是一個 static 方法 它可以對傳入的陣列進行排序, 由於陣列傳入是採傳參考值方式進行引數傳遞 ( 詳見下一章 ), 因此當我們透過該方法進行排序後, 陣列內容就是已經排序的結果, 其方法的宣告原型如下 : 語法 :static void sort(int[] a) 所屬類別 :java.util.arrays 功能 : 對整數陣列排序 69 5.4.2 對陣列排序 :Arrays.sort() 說明 : (1) 事實上, 這個 method 已經透過多載技術宣告了多種資料型態的參數, 因此即使您傳入的是其他資料型態 ( 例如 double) 的陣列, 它仍可以運作 註 : 6.10 節會深入說明多載技術宣告 (2) 同樣地, 這個 method 也透過多載技術, 使得我們可以指定陣列的排序範圍 詳見 Java 的類別說明文件 (3) 通常, 由程式語言或 IDE 提供的排序法都是效率較佳的排序法, 例如快速排序法 (quick sort) 實用範例 5-7 : 使用 Arrays sort() 改寫範例 5-2 範例 5-7:ch5_07.java( 隨書光碟 myjava\ch05\ch5_07.java) 70

5.4.2 對陣列排序 :Arrays.sort() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /* 檔名 :ch5_07.java 功能 : 對陣列排序 */ package myjava.ch05; import java.lang.*; import java.util.arrays; public class ch5_07 // 主類別 public static void main(string args[]) int x[]=25,10,39,40,33,12; int spec=11; 引入 Arrays 類別 Arrays.sort(x); for(int i=0;i<6;i++) System.out.print(x[i]+ "\t"); System.out.println("\n 特別號 \t" + spec); 71 5.4.2 對陣列排序 :Arrays.sort() 執行結果 : 10 12 25 33 39 40 特別號 11 範例說明 : 第 14 行會對 x 陣列進行排序, 我們在範例 5-2 使用的氣泡排序法效率不佳, 但本範例使用 Java 提供的排序不但效率更佳, 且不需要撰寫排序細節, 這種做法有助於發展大型程式 我們期望藉由這類範例, 讓讀者慢慢建立發展大型程式時的觀念 72

5.5 本章回顧 陣列 是一種非常重要的資料結構, Java 也支援 陣列 資料結構 並且 Java 的陣列索引值由 0 開始計算 我們在本章中學習到與陣列有關的知識如下 : (1) 使用陣列可以免除大量變數命名的問題, 使得程式具有較高的可讀性 (2) 陣列將會佔用連續的記憶體空間 (3) 陣列可以分為一維陣列 二維陣列 等等 而 Java 的二維陣列是由多個一維陣列所組成 (4) 陣列必須經由宣告名稱, 然後產生陣列實體, 最後即可透過索引存取陣列元素 73 5.5 本章回顧 (5)Java 的陣列名稱事實上是一個參考, 存放著陣列實體的位址 (6) 我們在宣告陣列的同時, 也可以指定陣列元素的初始值 (7)Java 的陣列提供了一些屬性與方法, 例如 length 屬性與 clone 方法 搜尋 與 排序 是程式設計的一項基本且重要的問題 所謂 搜尋, 指的是在一堆資料中, 尋找您所想要的資料 所謂 排序 則是將一堆雜亂的資料, 依照某個鍵值依序排列, 方便日後的查詢或使用 在本章中, 我們補充介紹了 氣泡排序法 74

5.5 本章回顧 在本章的最後, 我們介紹了一些陣列可以使用的方法 ( 隸屬於不同類別 ), 包含 System.arraycopy() 可用以複製陣列部份元素,Arrays.sort() 可以對陣列元素進行排序等 這些方法都是 static 方法, 不須產生物件實體, 並且把陣列當作是其中的引數傳入即可使用 由此可知, 在 Java 中, 我們不需要自行開發排序方法,Java 本身已經提供了效率優良的排序方法可供使用 75 本章結束 Q&A 討論時間 76