線性表的順序存儲又稱爲順序表數組
來看一個生活中的例子:週末和朋友一塊兒吃火鍋,人很是多,咱們須要在等候區等候,這個等候區就與順序表有很是多的類似之處,藉助它去理解順序表的特色。首先,在等候區有很是多的椅子,這些椅子每每是排成一排連續排放的,中間不會空出很大的空間形成浪費。這就與在順序表中選取存儲單元的方法是同樣的,咱們會選取一段地址連續的存儲單元去存放順序表。接着工做人員會安排咱們在椅子上連續的坐下等候。在存儲單元當中去進行數據的存放是同樣的,也是依次地存放線性表當中的數據元素,中間也不會空出許多存儲單元形成空間的浪費。最後結伴而行的朋友也會坐在相鄰的椅子上,這與順序表的存放是相同的。在邏輯上相鄰的兩個元素在物理位置上也要保證它相鄰,也會把它存放在相鄰的存儲單元上。在這個例子當中,其實椅子就表明着存儲單元,而每個等候的人就是要存放的數據元素。來總結一下順序表的特色:函數
一組地址連續存放的存儲單元依次存放線性表的元素,從而使得邏輯上相鄰的兩個元素在物理位置上也相鄰。設計
因此有這樣的規律:順序表中邏輯順序與物理順序相同3d
其中在邏輯上相鄰的兩個數據元素,在順序表中也存放在相同的存儲單元當中,每個小格子就表明一個存儲單元。指針
在程序語言設計中,每每使用數組來實現順序表。可是數組和順序表又有一些差異,第一個差異是數組下標是從 0 開始的,而順序表是從 1 開始的。還有一個就是數組的容量是不能夠增長的,而順序表的容量是能夠增長的。還有一些其餘的差異,好比說數組能夠是多維的,而順序表是一維的。code
根據順序存儲能夠知道,它是能夠實現隨機存取的。這是由於咱們能夠從第一個元素的地址直接推算出其餘元素的地址。在順序表當中,每個存放的元素都屬於同一種數據對象。那麼每個數據元素,它的大小都是同樣的。根據這一特色,咱們能夠計算出每個數據元素存儲的地址。對象
第一個元素的地址假設它是 LOC(A) ,計算第二個元素的地址就能夠用第一個元素的地址加上第一個數據元素 a1 所消耗的存儲空間,用 sizeof
可求得該數據元素所消耗的存儲空間大小。這裏須要注意的一點是,n 與 MaxSize 是有含義上的不一樣的,其中 an 表明的是順序表中最後一個數據元素,而 MaxSize 表明的是數組的最後一個存儲單元。blog
順序表能夠用數組來實現。根據數組的兩種分配方式,也就有兩種描述順序表的方法。分別是靜態描述分配順序表的方法和動態描述分配順序表的方法。首先來看數組靜態分配時時如何描述一個順序表的。內存
#define MaxSize 50 typedef struct{ ElemType data[MaxSize]; int length; }SqList;
這就是描述順序表的語句。第一句是定義了一個宏,也就是把 MaxSize 定義爲 50,這也就是數組的最大容量。接着定義了一個結構體。結構體就是把多個基本數據類型組合到一塊兒構成一個新的數據類型。它的定義語句是用 typedef struct
,而後用大括號圈起來所要包含的基本數據類型。最後 SqList
表明着該結構體的名字。這個結構體當中有一個存放順序表的數組,它是 ElemType 類型,其中數組大小是 MaxSize,也就是 50,還有一個整型的 length,它是表明順序表的長度。這就是一個順序表的程序設計語言描述。it
接下來看數組動態分配是如何描述順序表的。
#define MaxSize 50 typedef struct{ ElemType *data; int length; }SqList;
這是動態分配時描述順序表的語句,觀察發現這裏用的是指針,指針是存放一個存儲單元地址的。順序表根據第一個數據元素的地址和數據元素的大小,就能夠計算出任意數據元素的位置。那麼只要定義了第一個數據元素的指針,就能夠描述整個順序表。可是這一個變量它僅僅是一個地址,而沒有確切的空間,因此在使用時,須要動態的申請空間。怎樣動態的申請空間呢?有這樣兩條語句:
C L.data = (Elemtype*)malloc(sizeof(ElemType)*InitSize); C++ L.data = new ElemType[InitSize];
L 是 SqList 類型的一個變量,也就是 L 表明這一個順序表,接着用 malloc
這個動態函數來申請空間,函數參數部分是申請空間的大小,是用 sizeof
計算每個數據類型的大小乘以它的個數,就計算出整個須要申請空間的大小,malloc
前面的括號部分能夠理解爲強調了申請空間的類型。這是 C 語言中的方法。C++ 中直接 new 一個申請空間的類型和大小。
在使用動態分配時,必定要先申請空間才能使用,由於若是沒有申請空間,它僅僅是一塊地址,而沒用所須要的空間。
靜態分配和動態分配有什麼不一樣呢?其實也就是數組的不一樣。在靜態分配時,咱們在編寫的時候,就已經肯定了數組的大小。而動態分配時,沒有肯定它的大小,是根據動態分配語句在運行時纔將它的大小進行分配。這樣有一點的好處就是,在靜態分配時,當我想要存放順序表的數據元素過超過 50 的時候則會產生錯誤溢出,而動態分配時,若是一旦超過了分配的空間大小,能夠再從新分配一塊內存空間,把舊的空間和所增長的數據元素轉移到新申請的空間上,這樣就不會產生溢出的問題了。這是動態分配的一個優勢。
記住,動態分配依舊是一塊連續的存儲空間,絕非是鏈式存儲。