2. 基于数组的线性表实现¶
2.1. 基于数组的线性表实现¶
以下是基于数组实现的线性表,命名为 AList 。 AList 继承自 抽象数据类型 ,因此必须实现 List 的所有成员函数。
// Array-based list implementation
class AList<E> implements List<E> {
private E listArray[]; // Array holding list elements
private static final int DEFAULT_SIZE = 10; // Default size
private int maxSize; // Maximum size of list
private int listSize; // Current # of list items
private int curr; // Position of current element
// Constructors
// Create a new list object with maximum size "size"
@SuppressWarnings("unchecked") // Generic array allocation
AList(int size) {
maxSize = size;
listSize = curr = 0;
listArray = (E[])new Object[size]; // Create listArray
}
// Create a list with the default capacity
AList() {
this(DEFAULT_SIZE); // Just call the other constructor
}
public void clear() { // Reinitialize the list
listSize = curr = 0; // Simply reinitialize values
}
// Insert "it" at current position
public boolean insert(E it) {
if (listSize >= maxSize) {
return false;
}
for (int i=listSize; i>curr; i--) { // Shift elements up
listArray[i] = listArray[i-1]; // to make room
}
listArray[curr] = it;
listSize++; // Increment list size
return true;
}
// Append "it" to list
public boolean append(E it) {
if (listSize >= maxSize) {
return false;
}
listArray[listSize++] = it;
return true;
}
// Remove and return the current element
public E remove() {
if ((curr<0) || (curr>=listSize)) { // No current element
return null;
}
E it = listArray[curr]; // Copy the element
for(int i=curr; i<listSize-1; i++) {// Shift them down
listArray[i] = listArray[i+1];
}
listSize--; // Decrement size
return it;
}
public void moveToStart() { // Set to front
curr = 0;
}
public void moveToEnd() { // Set at end
curr = listSize;
}
public void prev() { // Move left
if (curr != 0) {
curr--;
}
}
public void next() { // Move right
if (curr < listSize) {
curr++;
}
}
public int length() { // Return list size
return listSize;
}
public int currPos() { // Return current position
return curr;
}
// Set current list position to "pos"
public boolean moveToPos(int pos) {
if ((pos < 0) || (pos > listSize)) {
return false;
}
curr = pos;
return true;
}
// Return true if current position is at end of the list
public boolean isAtEnd() {
return curr == listSize;
}
// Return the current element
public E getValue() {
if ((curr < 0) || (curr >= listSize)) // No current element
return null;
return listArray[curr];
}
//Tell if the list is empty or not
public boolean isEmpty() {
return listSize == 0;
}
}
// Array-based list implementation
class AList implements List {
private Object listArray[]; // Array holding list elements
private static final int DEFAULT_SIZE = 10; // Default size
private int maxSize; // Maximum size of list
private int listSize; // Current # of list items
private int curr; // Position of current element
// Constructors
// Create a new list object with maximum size "size"
AList(int size) {
maxSize = size;
listSize = curr = 0;
listArray = new Object[size]; // Create listArray
}
// Create a list with the default capacity
AList() { this(DEFAULT_SIZE); } // Just call the other constructor
public void clear() // Reinitialize the list
{ listSize = curr = 0; } // Simply reinitialize values
// Insert "it" at current position
public boolean insert(Object it) {
if (listSize >= maxSize) return false;
for (int i=listSize; i>curr; i--) // Shift elements up
listArray[i] = listArray[i-1]; // to make room
listArray[curr] = it;
listSize++; // Increment list size
return true;
}
// Append "it" to list
public boolean append(Object it) {
if (listSize >= maxSize) return false;
listArray[listSize++] = it;
return true;
}
// Remove and return the current element
public Object remove() {
if ((curr<0) || (curr>=listSize)) // No current element
return null;
Object it = listArray[curr]; // Copy the element
for(int i=curr; i<listSize-1; i++) // Shift them down
listArray[i] = listArray[i+1];
listSize--; // Decrement size
return it;
}
public void moveToStart() { curr = 0; } // Set to front
public void moveToEnd() { curr = listSize; } // Set at end
public void prev() { if (curr != 0) curr--; } // Move left
public void next() { if (curr < listSize) curr++; } // Move right
public int length() { return listSize; } // Return list size
public int currPos() { return curr; } // Return current position
// Set current list position to "pos"
public boolean moveToPos(int pos) {
if ((pos < 0) || (pos > listSize)) return false;
curr = pos;
return true;
}
// Return true if current position is at end of the list
public boolean isAtEnd() { return curr == listSize; }
// Return the current element
public Object getValue() {
if ((curr < 0) || (curr >= listSize)) // No current element
return null;
return listArray[curr];
}
// Check if the list is empty
public boolean isEmpty() { return listSize == 0; }
}
// Array-based list implementation
class AList : public List {
ListItemType* listArray; // Array holding list elements
static const int DEFAULT_SIZE = 10; // Default size
int maxSize; // Maximum size of list
int listSize; // Current # of list items
int curr; // Position of current element
public:
// Constructors
// Create a new list object with maximum size "size"
AList(int size = DEFAULT_SIZE) : listSize(0), curr(0) {
maxSize = size;
listArray = new ListItemType[size]; // Create listArray
}
~AList() { delete [] listArray; } // destructor to remove array
// Reinitialize the list
void clear() { listSize = curr = 0; } // Simply reinitialize values
// Insert "it" at current position
bool insert(const ListItemType& it) {
if (listSize >= maxSize) return false;
for (int i = listSize; i > curr; i--) // Shift elements up
listArray[i] = listArray[i-1]; // to make room
listArray[curr] = it;
listSize++; // Increment list size
return true;
}
// Append "it" to list
bool append(const ListItemType& it) {
if (listSize >= maxSize) return false;
listArray[listSize++] = it;
return true;
}
// Remove and return the current element
ListItemType remove() {
if ((curr < 0) || (curr >= listSize)) // No current element
throw std::out_of_range("remove() in AList has current of " + to_string(curr) + " and size of "
+ to_string(listSize) + " that is not a a valid element");
ListItemType it = listArray[curr]; // Copy the element
for(int i = curr; i < listSize-1; i++) // Shift them down
listArray[i] = listArray[i+1];
listSize--; // Decrement size
return it;
}
void moveToStart() { curr = 0; } // Set to front
void moveToEnd() { curr = listSize; } // Set at end
void prev() { if (curr != 0) curr--; } // Move left
void next() { if (curr < listSize) curr++; } // Move right
int length() { return listSize; } // Return list size
int currPos() { return curr; } // Return current position
// Set current list position to "pos"
bool moveToPos(int pos) {
if ((pos < 0) || (pos > listSize)) return false;
curr = pos;
return true;
}
// Return true if current position is at end of the list
bool isAtEnd() { return curr == listSize; }
// Return the current element
ListItemType getValue() {
if ((curr < 0) || (curr >= listSize)) // No current element
throw std::out_of_range("getvalue() in AList has current of " + to_string(curr) + + " and size of "
+ to_string(listSize) + " that is not a a valid element");
return listArray[curr];
}
// Check if the list is empty
bool isEmpty() { return listSize == 0; }
};
2.1.1. 插入¶
因为基于数组的线性表实现被定义为在数组的连续单元格中存储线性表元素,所以 insert 、 append 和 remove 方法必须保持这一属性。
2.1.2. 插入练习¶
2.2. 追加和移除¶
从线性表头部移除一个元素与插入类似,因为剩余的所有元素都必须向头部移动一个位置以填补空缺。如果我们想要移除位置 \(i\) 处的元素,那么 \(n - i - 1\) 个元素必须向头部移动,如下面的幻灯片所示。
在平均情况下,插入或删除各需要移动一半的元素,即 \(\Theta(n)\) 。
2.2.1. 移除练习练习¶
除了 insert 和 remove 之外,唯一可能需要超过常数时间的其他操作是构造器和 clear 。Class AList 的其他方法只是访问当前列表元素或移动当前位置。它们都需要 \(\Theta(1)\) 时间。

