順序表是最簡單的一種線性結構,邏輯上相鄰的數據在計算機內的存儲位置也是相鄰的,能夠快速定位第幾個元素,中間不容許有空,因此插入、刪除時須要移動大量元素。順序表能夠分配一段連續的存儲空間Maxsize,用elem記錄基地址,用length記錄實際的元素個數,即順序表的長度, 數組
上圖1表示的是順序表的基本形式,數據元素自己連續存儲,每一個元素所佔的存儲單元大小固定相同,元素的下標是其邏輯地址,而元素存儲的物理地址(實際內存地址)能夠經過存儲區的起始地址Loc (e0)加上邏輯地址(第i個元素)與存儲單元大小(c)的乘積計算而得,即:Loc(element i) = Loc(e0) + c*ispa
因此、訪問指定元素時無需從頭遍歷,經過計算即可得到對應地址,其時間複雜度爲O(1)。code
若是元素的大小不統一,則須採用圖2的元素外置的形式,將實際數據元素另行存儲,而順序表中各單元位置保存對應元素的地址信息(即連接)。因爲每一個連接所需的存儲量相同,經過上述公式,能夠計算出元素連接的存儲位置,然後順着連接找到實際存儲的數據元素。注意,圖2中的c再也不是數據元素的大小,而是存儲一個連接地址所需的存儲量,這個量一般很小。對象
圖2這樣的順序表也被稱爲對實際數據的索引,這是最簡單的索引結構。blog
一個順序表的完整信息包括兩部分,一部分是表中的元素集合,另外一部分是爲實現正確操做而需記錄的信息,即有關表的總體狀況的信息,這部分信息主要包括元素存儲區的容量和當前表中已有的元素個數兩項。索引
1爲一體式結構,存儲表信息的單元與元素存儲區以連續的方式安排在一塊存儲區裏,兩部分數據的總體造成一個完整的順序表對象。一體式結構總體性強,易於管理。可是因爲數據元素存儲區域是表對象的一部分,順序表建立後,元素存儲區就固定了。內存
2爲分離式結構,表對象裏只保存與整個表有關的信息(即容量和元素個數),實際數據元素存放在另外一個獨立的元素存儲區裏,經過連接與基本表對象關聯。element
一體式結構因爲順序表信息區與數據區連續存儲在一塊兒,因此若想更換數據區,則只能總體搬遷,即整個順序表對象(指存儲順序表的結構信息的區域)改變了。分離式結構若想更換數據區,只需將表信息區中的數據區連接地址更新便可,而該順序表對象不變。資源
採用分離式結構的順序表,若將數據區更換爲存儲空間更大的區域,則能夠在不改變表對象的前提下對其數據存儲區進行了擴充,全部使用這個表的地方都沒必要修改。只要程序的運行環境(計算機系統)還有空閒存儲,這種表結構就不會由於滿了而致使操做沒法進行。人們把採用這種技術實現的順序表稱爲動態順序表,由於其容量能夠在使用中動態變化。it
擴充的兩種策略
每次擴充增長固定數目的存儲位置,如每次擴充增長10個元素位置,這種策略可稱爲線性增加。
特色:節省空間,可是擴充操做頻繁,操做次數多。
每次擴充容量加倍,如每次擴充增長一倍存儲空間。
特色:減小了擴充操做的執行次數,但可能會浪費空間資源。以空間換時間,推薦的方式。
# 建立順序表 class Sequence_Table(): # 初始化 def __init__(self): self.date = [None]*100 self.length = 0 # 判斷是否已經滿了 def isFull(self): if self.length>100: print("該順序表已滿,沒法添加元素") return 1 else: return 0 # 按下表索引查找 def selectByIndex(self,index): if index>=0 and index<=self.length-1: return self.date[index] else: print("你輸入的下標不對,請從新輸入\n") return 0 # 按元素查下標 def selectByNum(self,num): isContain = 0 for i in range(0,self.length): if self.date[i] == num: isContain = 1 print("你要查找的元素下標是%d\n"%i) if isContain == 0: print("沒有找你你要的數據") # 追加數據 def addNum(self,num): if self.isFull() == 0: self.date[self.length] = num self.length += 1 # 打印順序表 def printAllNum(self): for i in range(self.length): print("a[%s]=%s"%(i,self.date[i]),end=" ") print("\n") # 按下標插入數據 def insertNumByIndex(self,num,index): if index<0 or index>self.length: return 0 self.length += 1 for i in range(self.length-1,index,-1): temp = self.date[i] self.date[i] = self.date[i-1] self.date[i-1] = temp self.date[index] = num return 1 # 按下標刪除數據 def delectNumByIndex(self,index): if self.length <= 0: print("該順序表內沒有數據,不用刪除") for i in range(index,self.length-1): temp = self.date[i] self.date[i] = self.date[i + 1] self.date[i + 1] = temp self.date[self.length-1] = 0 self.length -= 1 def main(): # 建立順序表對象 seq_t = Sequence_Table() # 插入三個元素 seq_t.addNum(1) seq_t.addNum(2) seq_t.addNum(3) # 打印驗證 seq_t.printAllNum() # 按照索引查找 num = seq_t.selectByIndex(2) print("你要查找的數據是%d\n" % num) # 按照索引插入數據 seq_t.insertNumByIndex(4, 1) seq_t.printAllNum() # 按照數字查下標 seq_t.selectByNum(4) #刪除數據 seq_t.delectNumByIndex(1) seq_t.printAllNum() if __name__ == "__main__": main()
運行結果爲:
a[0]=1 a[1]=2 a[2]=3 你要查找的數據是3 a[0]=1 a[1]=4 a[2]=2 a[3]=3 你要查找的元素下標是1 a[0]=1 a[1]=2 a[2]=3
#include<stdio.h> // 一、定義順序表的儲存結構 typedef struct { //用數組存儲線性表中的元素 int data[100]; // 順序表中的元素個數 int length; }Sequence_table,*p_Sequence_table; // 二、順序表的初始化, void initSequenceTable(p_Sequence_table T) { // 判斷傳過來的表是否爲空,爲空直接退出 if (T == NULL) { return; } // 設置默認長度爲0 T->length = 0; } // 三、求順序表的長度 int lengthOfSequenceTable(p_Sequence_table T) { if (T==NULL) { return 0; } return T->length; } // 四、判斷順序表是否已滿 int isFull(p_Sequence_table T) { if (T->length>=100) { printf("該順序表已經裝滿,沒法再添加元素"); return 1; } return 0; } // 五、按序號查找 int selectSequenceTableByIndex(p_Sequence_table T,int index) { if (index>=0&&index<=T->length-1) { return T->data[index]; } printf("你輸入的序號不對,請從新輸入\n"); return 0; } // 六、按內容查找是否存在 void selectSequenceTableByNum(p_Sequence_table T,int num) { int isContain = 0; for (int i=0; i<T->length; i++) { if (T->data[i] == num) { isContain = 1; printf("你要找的元素的下標是:%d\n",i); } } if (isContain == 0) { printf("沒有找到你要的數據\n"); } } // 七、添加元素(在隊尾添加) void addNumber(p_Sequence_table T,int num) { // 順序表尚未滿的時候 if (isFull(T) == 0) { T->data[T->length] = num; T->length++; } } // 八、順序表的遍歷 void printAllNumOfSequenceTable(p_Sequence_table T) { for (int i = 0; i<T->length; i++) { printf("T[%d]=%d ",i,T->data[i]); } printf("\n"); } //九、插入操做 int insertNumByIndex(p_Sequence_table T, int num,int index) { if (index<0||index>T->length) { return 0; } T->length++; for (int i = T->length-1; i>index; i--) { int temp = T->data[i]; T->data[i] = T->data[i-1]; T->data[i-1] = temp; } T->data[index] = num; return 1; } // 十、刪除元素 void delectNum(p_Sequence_table T,int index) { if (T->length <= 0) { printf("該順序表中沒有數據,不用刪除"); } for (int i = index;i<T->length-1; i++) { int temp = T->data[i]; T->data[i] = T->data[i+1]; T->data[i+1] = temp; } T->data[T->length-1] = 0; T->length--; } int main(int argc, const char * argv[]) { // 建立順序表的結構體 Sequence_table seq_t; // 初始化 initSequenceTable(&seq_t); // 添加數據 addNumber(&seq_t, 1); addNumber(&seq_t, 2); addNumber(&seq_t, 3); // 打印驗證 printAllNumOfSequenceTable(&seq_t); // 根據索引下標查內容 int num = selectSequenceTableByIndex(&seq_t, 2); printf("你查的數據是:%d\n",num); // 插入 insertNumByIndex(&seq_t, 4, 1); printAllNumOfSequenceTable(&seq_t); // 根據內容查下標 selectSequenceTableByNum(&seq_t, 4); // 根據下標刪除數據 delectNum(&seq_t, 1); printAllNumOfSequenceTable(&seq_t); return 0; }
運行結果爲:
T[0]=1 T[1]=2 T[2]=3 你查的數據是:3 T[0]=1 T[1]=4 T[2]=2 T[3]=3 你要找的元素的下標是:1 T[0]=1 T[1]=2 T[2]=3