順序表的定義


順序表的定義

線性表的順序存儲又稱為順序表

來看一個生活中的例子:周末和朋友一起吃火鍋,人非常多,我們需要在等候區等候,這個等候區就與順序表有非常多的相似之處,借助它去理解順序表的特點。首先,在等候區有非常多的椅子,這些椅子往往是排成一排連續排放的,中間不會空出很大的空間造成浪費。這就與在順序表中選取存儲單元的方法是一樣的,我們會選取一段地址連續的存儲單元去存放順序表。接着工作人員會安排我們在椅子上連續的坐下等候。在存儲單元當中去進行數據的存放是一樣的,也是依次地存放線性表當中的數據元素,中間也不會空出許多存儲單元造成空間的浪費。最后結伴而行的朋友也會坐在相鄰的椅子上,這與順序表的存放是相同的。在邏輯上相鄰的兩個元素在物理位置上也要保證它相鄰,也會把它存放在相鄰的存儲單元上。在這個例子當中,其實椅子就代表着存儲單元,而每一個等候的人就是要存放的數據元素。來總結一下順序表的特點:

一組地址連續存放的存儲單元依次存放線性表的元素,從而使得邏輯上相鄰的兩個元素在物理位置上也相鄰。

所以有這樣的規律:順序表中邏輯順序與物理順序相同

其中在邏輯上相鄰的兩個數據元素,在順序表中也存放在相同的存儲單元當中,每一個小格子就代表一個存儲單元。

在程序語言設計中,往往使用數組來實現順序表。但是數組和順序表又有一些差別,第一個差別是數組下標是從 0 開始的,而順序表是從 1 開始的。還有一個就是數組的容量是不可以增加的,而順序表的容量是可以增加的。還有一些其他的差別,比如說數組可以是多維的,而順序表是一維的。

根據順序存儲可以知道,它是可以實現隨機存取的。這是因為我們可以從第一個元素的地址直接推算出其他元素的地址。在順序表當中,每一個存放的元素都屬於同一種數據對象。那么每一個數據元素,它的大小都是一樣的。根據這一特點,我們可以計算出每一個數據元素存儲的地址。

第一個元素的地址假設它是 LOC(A) ,計算第二個元素的地址就可以用第一個元素的地址加上第一個數據元素 a1 所消耗的存儲空間,用 sizeof 可求得該數據元素所消耗的存儲空間大小。這里需要注意的一點是,n 與 MaxSize 是有含義上的不同的,其中 an 代表的是順序表中最后一個數據元素,而 MaxSize 代表的是數組的最后一個存儲單元。

順序表的兩種實現方法

順序表可以用數組來實現。根據數組的兩種分配方式,也就有兩種描述順序表的方法。分別是靜態描述分配順序表的方法和動態描述分配順序表的方法。首先來看數組靜態分配時時如何描述一個順序表的。

#define MaxSize 50
typedef struct{
    ElemType data[MaxSize];
    int length;
}SqList;

這就是描述順序表的語句。第一句是定義了一個宏,也就是把 MaxSize 定義為 50,這也就是數組的最大容量。接着定義了一個結構體。結構體就是把多個基本數據類型組合到一起構成一個新的數據類型。它的定義語句是用 typedef struct ,然后用大括號圈起來所要包含的基本數據類型。最后 SqList 代表着該結構體的名字。這個結構體當中有一個存放順序表的數組,它是 ElemType 類型,其中數組大小是 MaxSize,也就是 50,還有一個整型的 length,它是代表順序表的長度。這就是一個順序表的程序設計語言描述。

接下來看數組動態分配是如何描述順序表的。

#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 的時候則會產生錯誤溢出,而動態分配時,如果一旦超過了分配的空間大小,可以再重新分配一塊內存空間,把舊的空間和所增加的數據元素轉移到新申請的空間上,這樣就不會產生溢出的問題了。這是動態分配的一個優點。

記住,動態分配依舊是一塊連續的存儲空間,絕非是鏈式存儲。


免責聲明!

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



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