OpenDSA 完整目录

Chapter 9 Linear Structures

| 关于   «  2. 线性表 ADT   ::   目录   ::   4. 链表  »

3. 基于数组的线性表实现

3.1. 基于数组的线性表实现

以下是基于数组实现的线性表,命名为 AList 。 AList 继承自 抽象数据类型 ,因此必须实现 List 的所有成员函数。

// 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<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 : 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; }
};

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

3.1.1. 插入

因为基于数组的线性表实现被定义为在数组的连续单元格中存储线性表元素,所以 insert 、 append 和 remove 方法必须保持这一属性。

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

3.1.2. 插入练习

3.2. 追加和移除

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

从线性表头部移除一个元素与插入类似,因为剩余的所有元素都必须向头部移动一个位置以填补空缺。如果我们想要移除位置 \(i\) 处的元素,那么 \(n - i - 1\) 个元素必须向头部移动,如下面的幻灯片所示。

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

在平均情况下,插入或删除各需要移动一半的元素,即 \(\Theta(n)\) 。

3.2.1. 移除练习练习

除了 insert 和 remove 之外,唯一可能需要超过常数时间的其他操作是构造器和 clear 。Class AList 的其他方法只是访问当前列表元素或移动当前位置。它们都需要 \(\Theta(1)\) 时间。

3.3. 基于数组的线性表练习题

   «  2. 线性表 ADT   ::   目录   ::   4. 链表  »

关闭窗口