登 录
A Beta Version with much room for improvement.
package orderlink; /**有序链表。不允许有重复数据。 * @author Sodino * @version 1.0 beta*/ public class OrderLink { /**标识本链表中没有此元素。*/ public static final int NO_ELEMENT = -1; /** 默认的空间增量值。 */ public static final int DEFAULT_INCREMENT = 7; /**升序标识符。当为升序时为true,降序时为false。只可在构造函数中进行赋值。*/ private final boolean ascent; /** 当前链表已存储的整形数据元素个数。 */ private int size; /** 当前链表可以存储的整形数据的最多个数。 */ private int capability; /** 链表新增空间增量值。当array的长度不足时要新开辟的空间增量。 */ private int increment; /** 用于存储数据的数组。 */ private int[] array; /**新元素可插入的索引序号。默认值为NO_ELEMENT*/ private int insertIndex = NO_ELEMENT; /**构造一个有序链表并指定排序顺序。初始容量为DEFAULT_INCREMENT。 * @param ascent - 指定排序顺序。ascent为true表示升序,为false表示降序。*/ public OrderLink(boolean ascent) { this.ascent = ascent; this.capability = DEFAULT_INCREMENT; this.increment = DEFAULT_INCREMENT; this.size = 0; array = new int[this.capability]; } /**构造一个有序链表。 * @param capability - 指定本链表的初始容量 。 * @param increment - 指定本链表的增量值。 * @param ascent - 指定本链表的排序顺序。 * */ public OrderLink(int capability, int increment, boolean ascent) { this.capability = Math.max(DEFAULT_INCREMENT, capability); this.increment = Math.max(DEFAULT_INCREMENT, increment); this.ascent = ascent; size = 0; array = new int[this.capability]; } /**构造一个有序链表并将指定的数组数据添加进链表中。排序顺序为指定的升降序。 * @param arr - 指定的数组。 * @param ascent - 指定的排序顺序。*/ public OrderLink(int[] arr, boolean ascent) { this.ascent = ascent; this.capability = Math.max(arr.length, DEFAULT_INCREMENT); this.increment = DEFAULT_INCREMENT; this.size = 0; array = new int[this.capability]; add(arr); } /** * 获取指定的序号的数据。 * @param index - 指定的序号。 * @return 当index小于等于size时,返回指定的序号的数据值;如果大于index值,返回0。 */ public int get(int index) { if (index > size() - 1 || index < 0) { return 0; } return array[index]; } /**将指定的数组添加进本链表中。*/ public void add(int[] arr) { for (int i = 0; i < arr.length; i++) { add(arr[i]); } } /**往链表中添加进一个新数据。 * @param num - 将要添加进链表的数据。 * @return 如果添加成功,返回true,失败,即要添加的数据已经在本链表中存在了,则返回false。*/ public boolean add(int num) { int index = indexOf(num); if (index == NO_ELEMENT) { System.out.println("num = " + num + " insertIndex = " + insertIndex); insert(num, insertIndex); return true; } return false; } /**将指定的数据插入到指定序号的位置中。 * @param num - 指定要插入的数据。 * @param index - 指定的序号。*/ private void insert(int num, int index) { confirmCapability(size() + 1); System.arraycopy(array, insertIndex, array, insertIndex + 1, size() - insertIndex); array[insertIndex] = num; setSize(size() + 1); } /**查找指定的数在本链表中的序号。起始值为0。 * @param num - 指定的要查找的数。 * @return 如果查找到了,则返回在本链表中的序号。如果没找到则返回NO_ELEMENT。*/ public int indexOf(int num) { return binSearch(array, num); } /**删除指定序号的数。 * @param index - 指定要删除的序号。 * @return 删除成功返回true,否则返回false。*/ public boolean remove(int index) { if (index < 0 || index >= size()) { return false; } System.arraycopy(array, index + 1, array, index, size() - 1 - index); setSize(size() - 1); return true; } /** * 设置空间增量值。增量最小值默认为DEFAULT_INCREMENT。 */ public void setIncrement(int increment) { this.increment = Math.max(increment, DEFAULT_INCREMENT); } /** * 获取当前链表可以存储的整形数据的最多个数。 * * @return 当前链表可以存储的整形数据的最多个数。 */ public int getCapability() { return capability; } /** * 获取空间增量值。 * * @return 空间增量值。 */ public int getIncrement() { return increment; } /** * 删除所有的数据。 */ public void clear() { setSize(0); } /** * 设置新的size值。 * @param size - 新的size值。 */ private void setSize(int size) { this.size = size; } /** * 返回当前链表忆存储的整形数据个数。 * @return 当前链表忆存储的整形数据个数。 */ public int size() { return size; } /**获取排序信息。 * @return 升序返回true,降序返回false。*/ public boolean isAscent() { return ascent; } /**二分查找。 * @param array - 要查找的数组。 * @param num - 指定的要查找的数据。 * @return 如果查找到了,则返回在本链表中的序号。如果没找到则返回NO_ELEMENT。*/ private int binSearch(int[] array, int num) { // 初始工作。 insertIndex = NO_ELEMENT; int index = NO_ELEMENT; if (size() == 0) { insertIndex = 0; return index; } int lowIndex = 0, highIndex = size() - 1, midIndex = 0; while (lowIndex <= highIndex) { midIndex = (lowIndex + highIndex) >> 1; if (array[midIndex] == num) { index = midIndex; break; } // 确定insertIndex 的位置 if (lowIndex == highIndex) { // 都找完了,没找到 // 默认情况为: insertIndex = lowIndex; // 考虑特殊情况: if (isAscent()) { if (array[lowIndex] < num) { insertIndex = lowIndex + 1; } // 默认情况不作修改。 // else{ // insertIndex = lowIndex; // } } else { if (array[lowIndex] > num) { insertIndex = lowIndex + 1; } // 默认情况不作修改。 // else{ // insertIndex = lowIndex; // } } break; } // 二分查找 if (array[midIndex] > num) { if (isAscent()) { // highIndex = midIndex - 1;//用下面的句子代替本句是因为((low + // high)>>1)会有个向下取整。取整后若mid = low时且执行mid = high // -1,则出现high反而比low小的情况,异常。 highIndex = Math.max(lowIndex, midIndex - 1); } else { lowIndex = midIndex + 1; } } else { if (!isAscent()) { highIndex = Math.max(lowIndex, midIndex - 1); } else { lowIndex = midIndex + 1; } } } return index; } /** * <p> * 确认当前的OrderLink是否可以存储size大小的数据量。</p> * <p> * 如果不足以存储size大小的数据量,OrderLink将自动增加increment大小的空间。</p> * * @param size - 待验证的容量。 */ private void confirmCapability(int size) { int sub = size - getCapability(); if (sub > 0) { // 空间不足 // System.out.println("Capability is Inadequate!"); int incre = Math.max(increment, sub); addCapability(incre); } } /** * 一次性增加本链表的容量。 * * @param increment - 新增加的容量值。 * @return 容量增加成功返回true,失败返回false。 */ public boolean addCapability(int increment) { if (increment <= 0) { return false; } int newCapability = this.getCapability() + increment; int[] newArr = new int[newCapability]; this.capability = newCapability; System.arraycopy(array, 0, newArr, 0, array.length); array = null; array = newArr; // System.out.println("addCapabilityValue:" + increment); return true; } /** * 减少OrderLink的容量值。无论减少值为多少,OrderLink都保留至少DEFAULT_INCREMENT大小的最小容量。减少容量值过大可能会影响已存储了的数据。 * * @param decrement - 容量值的减少量。 * @return 容量减少成功返回true,失败返回false。 */ public boolean reduceCapability(int decrement) { if (decrement <= 0) { return false; } int maxDecrement = getCapability() - DEFAULT_INCREMENT; if (decrement > maxDecrement) { decrement = maxDecrement; } int newCapability = getCapability() - decrement; int[] newArr = new int[newCapability]; this.capability = newCapability; setSize(Math.min(size(), newCapability)); int copyLength = size(); System.arraycopy(array, 0, newArr, 0, copyLength); // System.out.println("newCap: " + this.getCapability() + // "copyLength: " // + copyLength); array = null; array = newArr; return true; } }
抱歉!评论已关闭.