地址:http://inmethetiger.iteye.com/blog/1707505
说明:原创是指习题答案。清单只是为了前后对应。
清单2.3
public class HighArrayApp { public static void main(String[] args){ int maxSize = 100; HighArray arr = new HighArray(maxSize); 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); arr.display(); int searchKey = 35; if(arr.find(searchKey)){ System.out.println("Found "+searchKey); }else{ System.out.println("Can't Found "+searchKey); } arr.delete(00); arr.delete(55); arr.delete(99); arr.display(); } } class HighArray { private long[] a;// 数组a的引用 private int nElems; public HighArray(int max) { a = new long[max]; nElems = 0; } public boolean find(long searchKey) { int j; for (j = 0; j < nElems; j++) { if (a[j] == searchKey) { break; } } if (j == nElems) { return false; } else return true; } public void insert(long value) { a[nElems] = value; nElems++; } public boolean delete(long value) { int j; for (j = 0; j < nElems; j++) //遍历查询 if (value == a[j]) break; if (j == nElems) return false; else { for (int k = j; k < nElems; k++) { a[k] = a[k + 1]; } nElems--; return true; } } public void display(){ for(int j=0;j<nElems;j++){ System.out.print(a[j]+"\t"); } System.out.println(); } }
清单2.4
public class OrderedApp { public static void main(String[] args) { int maxSize = 100; OrdArray arr = new OrdArray(maxSize); 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); arr.display(); int searchKey = 56; if (arr.find(searchKey) != -1) { System.out.println("Found " + searchKey); } else { System.out.println("Can't Found " + searchKey); } } } class OrdArray { private long[] a; private int nElems; public OrdArray(int max) { a = new long[max]; nElems = 0; } public int size() { return nElems; } // 采用二分查找,而不是2.3的线性查找了 public int find(long searchKey) { int lowerBound = 0; int upBound = nElems - 1; int curIn; //原著中,while条件为true。这样不行。因为如果找不到的话,会出现死循环 while (lowerBound < upBound) { curIn = (lowerBound + upBound) / 2; if (a[curIn] == searchKey) { return curIn; } else if (a[curIn] < searchKey) { lowerBound = curIn + 1; } else { upBound = curIn - 1; } } return -1; } public void insert(long value) { int j; for (j = 0; j < nElems; j++) if (a[j] > value) break; for (int k = nElems; k > j; k--) a[k] = a[k - 1]; a[j] = value; nElems++; } public boolean delete(long value) { int j = find(value); if (j == nElems) return false; else { for (int k = j; k < nElems; k++) a[k] = a[k + 1]; nElems--; return true; } } public void display() { for (int j = 0; j < nElems; j++) { System.out.print(a[j] + "\t"); } System.out.println(); } }
2.1:向HighArray.java(清单2.3)的HighArray类中添加一个名为getMax()的方法,它返回数组中最大关键字的值,当数组为空时返回-1。向main()中添加一些代码来使用这个方法。可以假设所有的关键字都是正数
代码实现:
public long getMax() { long max = -1; for (int i = 0; i < nElems; i++) { if (a[i] > max) { max = a[i]; } } return max; }
刚开始想复杂了,竟然想了替换。结果发现其实很简单:只需要将max和数组内的每个数比较,如果数组中的数大于max,则把max换成当前的数。
2.2:修改2.1中的方法,使之不仅能返回最大的关键字,而且还可以将该关键字从数组中删除,将这个方法命名为removeMax()
代码实现:
public void removeMax(){ delete(getMax()); } //main方法中 // 得到最大值 System.out.println(arr.getMax()); arr.removeMax(); arr.display();
2.3:修改2.2中的方法,提供了一种通过关键字进行数组排序的方法。实现一个排序方案,要去不修改HighArray类,只需对main()中的代码进行修改。这个方法需要第二个数组,在排序结束时数组数据项是逆序排列的。(这个方法是第三章“简单排序”中选择排序的一个遍体)
待实现:
public void removeMax2() { // 构造新数组,每次选出最大的放到新数组里面 long[] temp = new long[nElems]; /* * 1:通过getMax()得到最大的值,放到新构造的数组中。然后移除a数组中的值。 * 注意,i小于的条件是temp.length。而不是nElems。因为removeMax()的时候nElems已经减1了 */ for (int i = 0; i < temp.length; i++) { temp[i] = getMax(); removeMax(); } for (int i = 0; i < temp.length; i++) { System.out.print(temp[i] + "\t"); } }
2.4:修改清单2.4.史insert(),delete()和find()方法一样都使用二分查找。
这个修改起来还真复杂。关键是这个find方法不能复用。因为如果使用二分插入的方法的话,应该根据某个值能找到他的插入位置。但是find方法貌似不行。
最后修改了一下find方法。虽然能使用二分插入了。但是还是有问题。不过先帖在这里。到时候再改。
// 采用二分查找,而不是2.3的线性查找了 public int find(long searchKey) { int lowerBound = 0; int upBound = nElems - 1; int curIn; // 原著中,while条件为true。这样不行。因为如果找不到的话,会出现死循环 while (lowerBound < upBound) { curIn = (lowerBound + upBound) / 2; if (a[curIn] == searchKey) { return curIn; } else if (a[curIn] < searchKey) { lowerBound = curIn + 1; } else { upBound = curIn - 1; } } //如果 if(a[lowerBound]>searchKey) return lowerBound; else return lowerBound+1; } public void insert(long value) { int j; for (j = 0; j < nElems; j++) if (a[j] > value) break; for (int k = nElems; k > j; k--) a[k] = a[k - 1]; a[j] = value; nElems++; } public void insert2(long value) { // 应该用二分查找找到插入的位置,本来想服用find方法。发现那个方法不能返回位置信息 int index = find(value); for (int k = nElems; k > index; k--) a[k] = a[k - 1]; a[index] = value; nElems++; }
2.5是有序数组合并。
2.6:在清单之中加入一个noDup方法,使之可以将数组中的所有重复数据项删除。比如 数组中有三个17,则该方法会删除其中两个。不洗考虑保持数据项的顺序,一种方法是先用每一个数据项同其他数据比较,并用null(或是一个不会用在真正关键字中的特殊值)将重复的数据覆盖掉。然后将所有的null删掉。当然还要减小数组的大小。
解决办法没有细看。自己实现了一个。但是还是存在一点问题,比如如果最后几个相同的数放在一起,程序还是会保留两个重复的数。暂时没有解决
先帖出来:
public void noDup() { for (int i = 0; i < nElems; i++) { long temp =a[i]; for (int j = i+1; j <nElems; j++) { if(temp==a[j]) delete(a[j]); } } }