1. 程式人生 > >學好資料結構和演算法 —— 非線性結構(上)

學好資料結構和演算法 —— 非線性結構(上)

序言

上篇講到線性結構,和線性結構相反的是非線性結構,非線性結構特點是一個結點元素可能有多個直接前驅和多個直接後繼。常見的非線性結構有:二(多)維陣列、樹、圖。

本來計劃是非線性結構作為一篇,寫著寫著發現內容確實太多了,拆分為上、中、下3篇比較合適,所以改變了之前的計劃。

1、二維陣列

如:a[0][0]在水平方向有後繼a[0][1],垂直方向有後繼a[1][0],二維陣列從水平方向或垂直方向看,某個元素都有前驅或後繼,並不是線性結構。

二維陣列的表示方法

矩陣表示法

行向量表示法

列向量表示法

二維陣列的兩種儲存方式

其中行向量和列向量表示法分別對應二維陣列的行序為主序和列序為主序兩種儲存方式。對於任意一個二維陣列amxn

行序為主序儲存時,任意一個元素a[i][j]定址公式為:

&a[i][j] = &a[0][0] + (i * n + j) * data_size

其中:

  &a[i][j] : 為元素a[i][j]的地址

  &a[0][0]:為a[0][0]的儲存位置(即陣列的起始位置)

  data_size:數組裡儲存元素的長度

行序為主序儲存時,任意一個元素a[i][j]定址公式為:

&a[i][j] = &a[0][0] + (j * m + i) * data_size

公式引數參考列序儲存公式引數說明。

 

2、三(多)維陣列

相對於二維陣列來說,三維以及N(N>2)維陣列對於很多人來說可能不太熟悉,因為日常開發中用的比較少。對於三維陣列可以放到座標系裡類比,有了3個維度,如下圖所示:

分不了行和列了,其實返回去再看看二維陣列,行為主序儲存方式和列為主序儲存方式其實分別對應的就是以左下標作為主序儲存方式和以右下標作為主序儲存方式。對於三(多)維陣列來說也只有兩種儲存方式:以左下標作為主序儲存方式和以右下標作為主序儲存方式。

按左下標作為主序儲存

任意一個N(n>2)維陣列A[i1][i2]…[in],按左下標作為主序儲存時候,設A' = A[i1][i2]…[in-1

],那麼A[i1][i2]…[in]可以簡化為A'[0],A'[1],A'[2],…,A'[in - 1],然後儲存A'時候,也用左下標優先方式轉化為A''[0],A''[1],A''[2],…,A''[in-1 - 1],依次類推,當儲存最後1維陣列時為A[0][i2]…[in],A[1][i2]…[in],A[2][i2]…[in],…A[i1 - 1][i2]…[in],這樣就完成了N維陣列的儲存。

給定一個A[k1][k2]…[kn]元素,求它在陣列中儲存的位置可以依據公式:

對於三維陣列A[x][y][z]來說,當以左下標優先儲存時候,元素A[1][2][3]地址代入公式計算:

&A[1][2][3] = &A[0][0][0] + (3 + 2 * z + 1 * y * z) * data_size

按右下標作為主序儲存

任意一個N(n>2)維陣列A[i1][i2]…[in],按右下標作為主序儲存時候,設A' = A[i2]…[in-1][in],那麼A[i1][i2]…[in]可以簡化為A'[0],A'[1],A'[2],…,A'[i1 - 1],然後儲存A'時候,也用右下標優先方式轉化為A''[0],A''[1],A''[2],…,A''[i2 - 1],依次類推,當儲存第n維陣列時為A[i1][i2]…[in-1][0],A[i1][i2]…[in-1][1],A[i1][i2]…[in-1][in - 1],這樣就完成了N維陣列的儲存。

給定一個A[k1][k2]…[kn]元素,求它在陣列中儲存的位置可以依據公式:

對於三維陣列A[x][y][z]來說,當以右下標優先儲存時候,元素A[1][2][3]地址代入公式計算:

&A[1][2][3] = &A[0][0][0] + (1 + 2 * x + 3 * x * y) * data_size