數據結構描述的是數據之間的關系。C++數據結構的存儲方式有順序、鏈接、索引、散列等形式,對數據的處理通常包括輸入、輸出、查找、更新、排序、插入、刪除等,當數據的存儲方式不同時,相應的處理實現算法也不盡相同。如何采用一種簡便明了的方法分析C++的數據結構特點及各種存儲方式、處理方式之間的異同成為了計算機應用專業教育的一個難點。針對遠程開放教學學生大多數通過網絡課件自學這一特點,采用當今流行的跨平台程序設計語言java實現對C++數據結構算法的模擬,可以很好地解決對數據存儲方式、處理方式的具體化問題。利用java語言程序設計的靈活性及交互性,實現數據的動態輸入,自動、分步、循環執行存儲處理過程,並在internet上發布。 1、實現的功能
使用Java技術編寫的Java applet 程序,在網頁上發布,可以方便與用戶交互,用戶可以初始化算法元素,可以選擇執行方式(自動執行或單步執行);可以起止程序的執行;顯示當前程序運行的狀態;同步顯示算法描述與算法過程的變化。這裡我們以直接選擇排序(升序)為例子,來分析采用Java技術實現算法的摸擬演示。效果圖:
說明:"直接排序數據",文本框用來接收用戶輸入的數據。"排序數據個數",顯示用戶輸入的數據數。"當前最小值",當前程序執行時的最小值。"運行狀態",顯示當前程序運行狀態。"確定輸入",接收用戶的輸入。"自動執行",根據用戶的輸入自動進行排序演示。"單步執行",根據用戶的輸入,用戶可以手動控制程序的執行過程。"結束演示",結束演示,等待下一次演示。"列表框",在程序執行過程中與圖形變化同步顯示相對應的算法描述。
2、分析算法並將其轉化為圖形符號
直接選擇排序的基本思想是:每一趟 (例如第 i 趟,i = 0, 1, …, n-2) 在後面 n-i 個待排序對象中選出關鍵碼最小的對象, 作為有序對象序列的第 i 個對象。待到第 n-2 趟作完,待排序對象只剩下1個,就不用再選了。
它的基本步驟是:在一組對象v[i]~v[n-1]中選擇具有最小關鍵碼的對象;若它不是這組對象中的第一個對象,則將它與這組對象中的第一個對象對調; 在這組對象中剔除這個具有最小關鍵碼的對象,在剩下的對象v[i+1]~v[n-1]中重復執行前兩步,直到剩余對象只有一個為止。
下面將用一系列的圖形符號表示出該算法的執行過程。假設將對
36 25 48 12 65 43 20 58
這一組數據進行直接排序
向上箭頭前面為已排好序的數據,為一有序表;向上箭頭後面的數據為待排序區間,是一無序表;雙向向下箭頭表示兩數據交換。根據對排序過程分析,可以用下面圖形符號表示算法中的元素:
5、對演示過程的控制
對演示過程的控制在這裡用按鈕方式主要實現程序的起始、自動執行、單步執行。這裡采用的線程,在程序中定義一線程Thread allinone,所以我們將用一個run()過程放置程序主體部分-----包括對數據的排序和圖形、列表的對應顯示。可以用allinone.start()來開始程序,用allinone.stop()來結束程序。可以用allinone.start()來開始程序並自動執行run()中的程序體,執行過程較快,可以用Thread.sleep(100 )來暫停1秒。在run()中設置了變量step,當step==1時,即進入單步執行。這時使用suspend() 使線程掛起,暫停運行。當執行下一步時,使用resume() 恢復掛起的線程,使處於可運行狀態。
6、程序對異常的實現
對於程序的異常處理,可以采用 try {} catch(InterruptedException e){}來捕捉,並執行相應的處理。
7、程序的發布
java applet 可以插入普通網頁中。利用普通web服務器進行對外發布,在網頁中采用插入:<applet code="文件名.class" codebase = 文件相對路徑 width="" height=""></applet> html語句來實現。
8、結束語
通過以上幾步,再按照java applet程序的一般結構完整程序,就可基本實現利用java對C++數據結構算法描述的模擬,雖然這裡只舉了直接選擇排序的例子,但其他描述的模擬也可以使用以上方法實現。望本文能起到拋磚引玉作用,使java技術能在工作、生活中更多的應用。
其中,向下箭頭表示當前正在排序區間內查找的元素,向上箭頭為當前排序區間的開始位置。
3、輸入輸出處理的實現
為了增強模擬程序的交互性,在程序中將引入元素的用戶輸入、程序執行過程中算法描述同步執行、程序運行狀態的顯示。在程序界面上定義一個單行文本框來讓用戶輸入元素,並將定義初始元素(定義可以放在init()中):
TextField edit1;
edit1 = new TextField(22);
add(edit1);
edit1.setText("36 25 48 12 65 43 20 58");
在程序中定義StreamTokenizer類和array[]數組來接收用戶輸入的數據。 StreamTokenizer即令牌化輸入流的作用是將一個輸入流變成令牌流。這裡使用的是StreamTokenizer.TT_NUMBER: 表示讀到的令牌是數字,數字的值是double型,可以從實例變量nval中讀取。
StringTokenizer stringt = new StringTokenizer(edit1.getText());
array = new int[stringt.countTokens() + 1];//定義數組
for(int i = 1; stringt.hasMoreTokens(); i++)//數組賦值
array[i] =Integer.valueOf(stringt.nextToken()).intValue();
定義一個列表框list1用於對程序執行過程時算法描述的同步顯示,並將算法描述按執行順序分步初始化給列表:
list1 = new java.awt.List();
add(list1);
list1.addItem("template 〈class Type〉 void Sort(datalist〈Type〉 &list){"};
……
list1.addItem(")");
當程序執行時,采用list1.select()來選中相應的算法描述語句。在程序界面上定義一單行文本框edit5用於運行狀態的顯示:
TextField edit5; Edit5 = new TextField(22); add(edit5);
利用其edit5.setText(string)來顯示當前程序運行狀態。
4、用java語言描述圖形符號
在java 中,可以利用其方便的繪圖語句來實現以上圖形符號。包括表中元素的移動,兩種箭頭的移動。在表元素移動時可以將表與元素分離,表在元素移動時不需重繪,元素移動時也只需將元素按照排序的需要使用repaint()進行重繪。 構建一個表中圖形實現元素移動,語句放在
public void paint(Graphics g){}中執行:
for(int i = 1; i 〈 array.length; i++)
{ g.drawString(String.valueOf(array[i]),X, Y);}
元素的重繪根據排序的需要執行,下面語句實現了元素的排序及元素的移動(在run()中實現):
nowup_p = 3;
nowdown_p = 1;
for(nowdown_p = 1; nowdown_p 〈 array.length - 1; nowdown_p++)
{ int aa = array[nowdown_p];int aap = nowdown_p;
for(nowup_p = nowdown_p + 1; nowup_p 〈 array.length; nowup_p++)
{ repaint();
if(aa 〉 array[nowup_p])
{ aa = array[nowup_p];aap = nowup_p;}
Thread.sleep(100);}
array[aap] = array[nowdown_p];array[nowdown_p] = aa;
repaint();}
nowup_p = nowdown_p = 0;
repaint();}
箭頭的移動,利用了上述程序體中nowdown_p、nowdown_p的改變,利用g.drawline()、g.setColor()語句來完成。