計算機基礎數據結構講解第五篇-順序表


  本篇及下一篇文章介紹線性表,包括線性表的定義及順序表和鏈表的表示和方法。有關b樹的補充等到之后進行介紹。

一:線性表的定義和基本操作

  線性表是具有相同數據類型數據元素的有限序列集合,當線性表內沒有元素時,是一個空表用a(i)代表第i個數據元素,第一個元素為表頭,最后一個元素為表尾。除第一個元素外,每個元素都有一個直接前驅;除最后一個元素外,每個元素都有一個直接后繼。
  線性表是一個邏輯結構,表示元素之間一一對應的關系;而順序表和鏈式表是指存儲結構。
  線性表的基本操作是最基本的操作,包括:
  InitList(&L):初始化一個空的線性表。
  Length(L):求表長。
  LocateElem(L,e):在表中查找給定關鍵字值的元素。
  GetElem(L,i):在表中查找第i個位置的元素的值。
  ListInsert(&L,i,e):在表中的第i個位置插入元素e。
  ListDelete(&L,i,&e):刪除表中第i個位置元素,並用e返回。
  PrintList(L):輸出線性表中的所有元素值。
  Empty(L):判斷線性表是否為空。
  DestoryList(&L):銷毀線性表,並釋放線性表所占用的內存空間。
  這里的"&"表示的是c++里面的引用調用,傳入指針變量的時候要對傳入的指針進行改變,則會用到指針變量的引用型。在C語言的采用指針的指針也可以達到同樣的效果。

二:線性表的順序存儲

1.定義

  線性表的順序存儲又稱順序表,用一組地址連續的存儲單元依次存儲線性表的數據元素,使邏輯上相鄰的元素物理位置上也相鄰。i為元素a(i)的位序,特點是表中的邏輯順序與其物理順序相同。
  有關順序表的基本模型和結構這里就不詳細介紹了,主要是順序表是依靠數組實現的,要注意的是:線性表中元素的位序是從1開始的,而數組中元素的位序是從0開始的。

2.順序存儲數據類型

  由於順序表是由數組實現的,我們知道一維數組可以是靜態分配的,也可以是動態分配的。靜態分配因為空間和大小有限,一旦占滿,再加入新的數據將會產生溢出,導致程序崩潰;動態分配,數組空間是在需要時通過動態存儲語句分配,可以不斷開辟新的存儲空間,擴充存儲空間,所以更高效。
  順序存儲數據類型實現的代碼如下:

// 順序表的靜態存儲
#define MaxSize 50          //順序表最大長度
typedef struct{
  ElemType data[MaxSize];  //順序表數據元素
  int length;              //順序表當前長度
}SqList;                   //順序表結構體類型定義

//順序表的動態存儲
#define InitSize 100       //表長度的初始定義
typedef struct{
  ElemType *data;          //動態分配數組指針
  int MaxSize;length;      //數組最大容量和當前個數
}SeqList;                  //順序表結構體類型定義

  C語言初始動態分配語句是:
L.data= (ElemType)malloc(sizeof(ElemType)InitSize);
  C++的動態分配語句是:
L.data = new ElemType(InitList);

3.順序表基本操作的實現(代碼寫的是靜態存儲,動態存儲類似)

(1)插入操作

  在順序表L的第i個位置插入新元素e。如果i的輸入不合法,則返回false,表示插入失敗;否則將原順序表的第i個元素及其后面的所有元素右移一個位置,騰出一個空間插入新元素e。順序表的長度加一,插入成功,返回true。插入位置范圍從1到L.length+1,代碼如下:

bool ListInsert(SqList &L,int i,ElemType e){
  if(i < 1|| i > Length + 1)
    return false;
  if(L.length >= MaxSize)     //當前存儲空間已滿,不能插入
    return false;
  for(int j = L.length;j >= i;j--){     //將i及之后的元素后移
    L.data[j] = L.data[j-1];
  }
  L.data[i-1] = e;  //數組從0開始
  L.length++;
  return true;
}

  插入操作的最好情況是在表尾插,后移操作不再進行;最壞情況是在表頭插,后移n次。而平均情況下,插入的平均時間復雜度是O(n)。

(2)刪除操作

  刪除表中的第i個位置的元素,成功返回true,並將被刪除的元素用引用變量e返回,否則返回false,也需要移動元素位置。刪除位置范圍從1到L.length,代碼如下:

bool ListDelete(SqList &L,int i,ElemType &e){
  if(i < 1|| i > Length)
    return false;
  e = L.data[i-1];
  for(int j = i;j < L.length;j++){     //將i及之后的元素前移
    L.data[j-1] = L.data[j];
  }
  L.length--;
  return true;
}

  插入操作的最好情況是在表尾插,前移操作不再進行;最壞情況是在表頭插,前移n-1個數據元素。而平均情況下,刪除的平均時間復雜度是O(n)。

(3)簡單的按值查找

  在順序表中查找第一個元素值等於e的元素,並返回其位序。代碼如下:

int LocateElem(SqList L,ElemType e){
  int i;
  for(i = 0;i < L.length;i++)
    if(L.data[i] == e)
      return i + 1;             //位序從一開始
  return 0;
}

  最好情況在表頭比較一次,在表尾或不存在比較n次,按值查找的平均時間復雜度為O(n)。

4.順序表的特點

  優點:隨機訪問,在O(1)的時間內找到指定的元素。存儲密度高,每個結點只存儲數據元素。
  缺點:插入和刪除操作需要移動大量元素。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM