數據結構
數組擴容–如何對一個數組進行有效的擴容
- 靜態空間管理:開闢內部數組並適用一段地址連續的物理空間,capacity爲總容量,size爲當前的實際規模。若採用靜態空間策略管理,容量capacity固定,則存在明顯的不足。
上溢:capacity空間不夠,不足以存放所有元素
下溢:capcity空間過大,存放的元素寥寥無幾,裝填因子(load factor) u=size/capacity << 50%
而在一般的環境種無法預測空間的需求量,因此需要進行動態的擴容
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {0,6,5,1,9,10};
int[] a = {1,2,5,6,7,9,10};
}
public static int[] copyFrom(int[] array, int low, int high) {
int[] newArray = new int[2*(high-low)];
int size = 0;
while(low < high) {
newArray[size++] = array[low++];
}
return newArray;
}
}
</pre>
2.動態空間管理的思想:在即將發生上溢時,適當的擴大內部數組的容量。主要有兩種擴容策略:
a. 第一種爲容量遞增策略:即每次在即將上溢時,給系統增加固定的容量。
b. 第二種爲容量加倍策略:即在每次即將上溢時,在系統容量的基礎上容量加倍。
兩種增容算法的性能如下圖所示:
無序向量
- 元素訪問
- 元素插入: 由於我們這裏採用的是用數組進行元素插入,因此在插入之前我們需要先對數組進行擴容,再插入
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {0,6,5,1,9,10};
int[] newArray;
newArray = insert(b, 1, 100);
for (int j = 0; j < newArray.length; j++) {
System.out.println(newArray[j]);
}
}
public static int[] insert(int[] array, int rank, int num) {
int[] newArray;
newArray = copyFrom(array,0,array.length);
for (int i = array.length-1; i >= rank; i--) {
newArray[i+1] = newArray[i];
}
newArray[rank] = num;
return newArray;
}
public static int[] copyFrom(int[] array, int low, int high) {
int[] newArray = new int[2*(high-low)];
int size = 0;
while(low < high) {
newArray[size++] = array[low++];
}
return newArray;
}
}
</pre>
3.區間刪除: 刪除[low,high)中的元素
<pre>
public class LinearRecur {
public static void main(String[] args) { //0<=low<=high<=size
int[] b = {0,6,5,1,9,10};
int[] newArray;
newArray = delete(b, 1, 3);
for (int j = 0; j < newArray.length; j++) {
System.out.println(newArray[j]);
}
}
public static int[] delete(int[] array, int low, int high) { //0<=low<=high<=size
if(low == high) {
return array; //單獨處理退化的情況
}
while(high < array.length) {
array[low++] = array[high++];
}
while(low < array.length) { //爲了清除後面的內容
array[low++] = 0;
}
return array;
}
}
</pre>
4.刪除:單元素刪除操作:
可以通過調用區間刪除操作來實現:remove = delete[rank,rank+1),刪除的區間只包含一個元素
但是區間刪除,不能夠調用單個刪除來實現,因爲這樣會導致時間複雜度變爲O(n^2)
5.查找:查找某一指定元素
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {0,6,5,1,9,10};
int index = 0;
index = find(b,0,3,5);
System.out.println(index);
}
public static int find(int[] array, int low, int high, int num) { //從[low,high)中查找num
while(high-- > low) {
if(array[high] == num) {
break;
}
}
return high;
}
}
</pre>
6.唯一化:刪除數組中的重複元素
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {2,6,6,6,2,9,10};
int[] array;
array = unique(b);
for (int i = 0; i < array.length; i++) {
System.out.printf("%d", array[i]);
}
}
public static int[] unique(int[] array) {
int index = 0;
int[] newArray;
int i = 1;
while(i < array.length){
index = find(array,0,i,array[i]);
if (index != -1) {
array = delete(array, index,index+1);
}else if(array[i] == 0){ //爲了防止0的出現導致死循環
break;
}else {
i++;
}
}
return array;
}
public static int find(int[] array, int low, int high, int num) { //從[low,high)中查找num
while(high-- > low) {
if(array[high] == num) {
break;
}
}
return high;
}
public static int[] delete(int[] array, int low, int high) { //0<=low<=high<=size
if(low == high) {
return array; //單獨處理退化的情況
}
while(high < array.length) {
array[low++] = array[high++];
}
while(low < array.length) { //爲了清除後面的內容
array[low++] = 0;
}
return array;
}
}
e(high < array.length) {
array[low++] = array[high++];
}
while(low < array.length) { //爲了清除後面的內容
array[low++] = 0;
}
return array;
}
}
</pre>
有序性及其甄別
有序/無序序列中,任意。/總有一對相鄰元素順序/逆序
相較於無序數組的唯一化,有序數組的唯一化可以有更加簡單的實現形式。之前唯一化算法的低效在於對於同一元素作爲被刪除元素的後繼需要進行多次前移,這就導致無序數組的唯一化具有低效的性能。而有序數組若能以區間爲單位,刪除重複元素勢必將大大提高算法的性能,同時有序數組無需向前查找,這也是算法提高性能的一個方面。下面是有序數組唯一化的實現過程。
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {2,6,6,9,10,10};
int[] array;
array = unique(b);
for (int i = 0; i < array.length; i++) {
System.out.printf("%d", array[i]);
}
}
public static int[] unique(int[] array) {
int index1=0;
int index2 =0;
while(++index2 < array.length) {
if(array[index2] != array[index1]){
array = delete(array, index1+1, index2);
index1 += 1;
index2 = index1;
}
if(array[index2] == 0) {
break;
}
}
return array;
}
public static int[] delete(int[] array, int low, int high) { //0<=low<=high<=size
if(low == high) {
return array; //單獨處理退化的情況
}
while(high < array.length) {
array[low++] = array[high++];
}
while(low < array.length) { //爲了清除後面的內容
array[low++] = 0;
}
return array;
}
}
</pre>