Higharray.java 源碼
/*
* 下述的作業題源自<<Java數據結構和算法(第二版)>>每章結束後留給的問題,
* 它們涵蓋了每章的所有重點。目地在於自測,以確保自己已經基本理解該章的內容。
* 題源:第2章 數組
* 作者:半點閒
* 時間:2008.6.19
*/
package Higharray;
/**
*
* @author bdx
*/
class HighArray{
public HighArray(int max) //constructor
{
a = new long[max]; //create the array
nElems = 0; //no items yet
}
public boolean find (long searchkey) //find specified value
{
int j;
for(j=0; j<nElems; j++) //for each element,
if(a[j] == searchkey) //found item?
break; //exit loop before end
if(j == nElems) //gone to end?
return false; //yes,can't find it
else
return true; //no,found it
}
public void insert (long value) //put element into array
{
a[nElems] = value; //insert it
nElems++; //increment size
}
public boolean delete (long value)
{
int j;
for(j=0; j<nElems; j++) //look for it
if(value == a[j])
break;
if(j == nElems) //can't find it
return false;
else
{
for(int k=j; k<nElems; k++) //move higher ones down
a[k] = a[k+1];
nElems--;
return true;
}
}
public void display() //displays array contents
{
for(int j=0; j<nElems; j++) //for each element
System.out.print(a[j] + " "); //display it
System.out.println();
}
/**
* 編程作業:2.1向highArray.java程序(清單2.3)的HighArray類添加名爲getMax()的方法,
* 它返回數組中最大關鍵字的值,當數組爲空時返回-1。向main()中添加一些代碼來使用這個方法。
* 可以假設所有關鍵字都是正數。
* 功能:獲取數組中最大關鍵字的值。當數組爲空時返回-1。
* @return long
*/
public long getMax(){
if(nElems == 0) return -1; //數組爲空。
long lmax = a[0];
for(int i=1; i<nElems; i++)
if(lmax < a[i]) lmax = a[i];
return lmax;
}
/**
* 編程作業:2.2修改編程作業2.1中的方法,使之不僅返回最大的關鍵字,而且還將關鍵字從數組中刪除。
* 將這個方法命名爲removeMax()。
* 功能:將最大關鍵字從數組中刪除。成功返回true,否則false。
* @return boolean
*/
public boolean removeMax (){
/**
* 思考:找到最大關鍵字可以通過現有getMax()方法來實現,刪除功能可以通過現有的delete(long)
* 來實現。
*/
if(getMax() == -1) return false;
return delete(getMax());
}
/**
* 編程作業:2.6 向highArray.java程序(清單2.3)的HighArray類中加入一個noDup()的方
* 法,使之可以將數組中的所有重複數據項刪除.即如果數組中有三個數據項的關鍵字爲17,
* noDup()方法將會刪除其中的兩個.不必考試保持數據項的順序.一種方法是先用每一個數據
* 項比較,並用null(或是一個不會用在真正的關鍵字中的特殊值)將重複的數據項覆蓋掉。然
* 後將所有的null刪除,當然還要縮小數組的大小。
*/
public void noDup()
{
//標記部分
int nCount = 0; //標記計數器。
for(int i=0; i<nElems; i++)
for(int j=0; j<i; j++)
if(a[j] == a[i])
{
if(a[i] != -1) //排除特殊標記
{
a[i] = -1; //特殊標記,假設用戶不會輸入負值。
nCount++;
}
}
//調整部分
long[] b = new long[nElems - nCount];
int nLength = 0;
for(int i=0; i<nElems; i++)
if(a[i] != -1)
{
b[nElems - nCount - 1 - i] = a[i];
nLength++;
}
//賦值部份
nElems = nLength;
a = b;
}
private long[] a; //ref to array a
private int nElems; //number of data items
}
public class HighArrayApp{
public static void main (String[] args){
int maxSize = 100; //array size
HighArray arr; //reference to array
arr = new HighArray(maxSize); //create the array
arr.insert(77); //insert 10 items
arr.insert(99);
arr.insert(44);
arr.insert(55);
arr.insert(22);
arr.insert(88);
arr.insert(11);
arr.insert(00);
arr.insert(66);
arr.insert(33);
arr.display(); //display array
int searchKey = 35;
if(arr.find(searchKey))
System.out.println("Found " + searchKey);
else
System.out.println("Can't find " + searchKey);
arr.delete(00); //delete 3 items
arr.delete(55);
arr.delete(99);
arr.display(); //display array
System.out.println("默認演示結束");
//編程作業:2.1
if(arr.getMax() != -1)
{
System.out.println("當前數組中最大的數是:" + arr.getMax());
System.out.println("刪除最大關鍵字:" + arr.removeMax());
}
arr.display(); //display array
System.out.println("編程作業:2.1演示結束");
/**
* 編程作業:2.3編程作業2.2中的removeMax()方法提供了一種通過關鍵字值進行數組排序的方
* 法。實現一個排序方案,要求不修改HighArray類,只需對main()中的代碼進行修改。這個方
* 法需要第二個數組,在排序結束時數組數據項是逆序排列的。(這個方法是第3章“簡單排序”中選
* 擇排序的一個變體.)
* 作者聲明:下面代碼只完成上述要求,算法不做其它處理。
*/
HighArray higthSort = new HighArray(maxSize);
for(int i=0; i<maxSize; i++){
higthSort.insert(arr.getMax());
arr.removeMax();
}
higthSort.display(); //display array
System.out.println("編程作業:2.3演示結束");
/**
* 編程作業:2.6
*/
arr.insert(55);
arr.insert(44);
arr.insert(44);
arr.insert(55);
arr.noDup();
arr.display();
System.out.println("編程作業:2.6演示結束");
}
}
OrderedApp.java 部分
/* * 下述的作業題源自<<Java數據結構和算法(第二版)>>每章結束後留給的問題, * 它們涵蓋了每章的所有重點。目地在於自測,以確保自己已經基本理解該章的內容。 * 題源:第2章 數組 * 作者:半點閒 * 時間:2008.6.19 */ /** * 編程作業:2.4修改orderedArray.java程序(清單2.4)使insert()、delete()與find()方法一 * 樣都使用二分查找,正如書中所建議的那樣。 * 編程作業:2.5向OrderdApp.java程序(清單2.4)的OrdArray類加入一個merge()方法,使之 * 可以將兩個有序的源數組合併成一個有序的目的數組。在main()中添加代碼,向兩個源數組中 * 插入隨機數,調用merge()方法,並將結果目的數組顯示出來。兩個源數組的數據項個數可能不 * 同。在算法中需要先比較數組中的關鍵字,從中選出最小的一個數據項複製到目的數組。同時還 * 要考慮如何解決當一個源數組的數據項已經取完而另一個還剩一些數據項的情況。 */ package OrderedApp; import java.util.Random; /** * * @author bdx */ public class Main { /** * @param args the command line arguments */ public static void main(String[] args) { int maxSize = 100; //array size OrdArray arr = new OrdArray(maxSize); //create the array arr.insert(77); arr.insert(99); arr.insert(44); arr.insert(55); arr.insert(22); arr.insert(88); arr.insert(11); arr.insert(00); arr.insert(66); arr.insert(33); int searchKey = 55; //serch for item if( arr.find(searchKey) != arr.size() ) System.out.println("Found" + searchKey); else System.out.println("Can't find" + searchKey); arr.display(); //display items arr.delete(00); //delete 3 items arr.delete(55); arr.delete(99); arr.display(); //display items again System.out.println("默認演示結束。"); /** * 編程作業:2.5 */ OrdArray arr1 = new OrdArray(10); OrdArray arr2 = new OrdArray(5); Random random1 = new Random (); Random random2 = new Random (); for(int i=0; i<10; i++){ arr1.insert(Math.abs(random1.nextInt()%1000)); } for(int i=0; i<5; i++){ arr2.insert(Math.abs(random2.nextInt()%1000)); } arr1.display(); arr2.display(); OrdArray arr3 = OrdArray.merge(arr1, arr2); arr3.display(); System.out.println("編程作業:2.5演示結束。"); } } class OrdArray{ public OrdArray (int max) //constructor { a = new long[max]; nElems = 0; } public int size (){ return nElems; } public int find (long searchKey){ int lowerBound = 0; int upperBound = nElems - 1; int curIn; while(true){ curIn = (lowerBound + upperBound) / 2; if(a[curIn] == searchKey) return curIn; //found it else if(lowerBound > upperBound) return nElems; //can't find it else { if(a[curIn] < searchKey) lowerBound = curIn + 1; //it's in upper half else upperBound = curIn - 1; //it's in lower half } } } public void insert (long value) { /** * 作業2.4 * 算法說明:用"二分查找"找插入值合適位置。插入後的數組中的數據項按升序排列。 * 註明:爲了減少檢查用戶輸入的值與數組中的數據項是否有重複的代碼,現假設用 * 戶輸入的值都是不重複的。 */ int lowerBound = 0; int upperBound = nElems - 1; int curIn = lowerBound; while (true) { curIn = (lowerBound + upperBound) / 2; //拆分 /** * lowerBound = upperBound,範圍是一個數據項所以還需要再一次循環。 * lowerBound > upperBound,則範圍已經不存在了。 */ if(lowerBound > upperBound) break; if(a[curIn] < value) lowerBound = curIn + 1; else upperBound = curIn - 1; } for(int k=nElems; k>curIn; k--) a[k] = a[k - 1]; a[lowerBound] = value; nElems++; } public static OrdArray merge (OrdArray arr1, OrdArray arr2) { /** * 編程作業:2.5 * merge()方法,使之可以將兩個有序的源數組合併成一個有序的目的數組......兩 * 個源數組的數據項個數可能不同。在算法中需要先比較數組中的關鍵字,從中選出 * 最小的一個數據項複製到目的數組。同時還要考慮如何解決當一個源數組的數據項 * 已經取完而另一個還剩一些數據項的情況。 * * 算法說明:力求完成上述作業求,同時讓算法清晰,其它情況都不予處理(如: * 檢查參數中的數組是否爲空等等)。 */ int nLen1 = arr1.size(); int nLen2 = arr2.size(); int i = 0, j = 0; OrdArray ret = new OrdArray (nLen1 + nLen2); while(i < nLen1 && j < nLen2) { if(arr1.getValue(i) < arr2.getValue(j)) { ret.insert(arr1.getValue(i++)); } else { ret.insert(arr2.getValue(j++)); } } if(i == nLen1) // 如果array1已經被拷貝完畢就拷貝array2的元素 { while (j < nLen2) ret.insert(arr2.getValue(j++)); } else // 如果array2已經被拷貝完畢就拷貝array1的元素 { while (i < nLen1) ret.insert(arr1.getValue(i++)); } return ret; } public long getValue (int index){ /** * 功能:返回給定索引值的數據項。 */ return a[index]; } public boolean delete (long value) { int j = find (value); if(j == nElems) //can't find it return false; else { for(int k=j; k<nElems; k++) //move bigger ones down a[k] = a[k+1]; nElems--; //decrement size return true; } } public void display() //displays array contents { for(int j=0; j<nElems; j++) //for each element System.out.print(a[j] + " "); // display it System.out.println(); } private long[] a; //ref to array a private int nElems; //number of data items }