學好數據結構和算法 —— 非線性結構(上)


序言

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

本來計划是非線性結構作為一篇,寫着寫着發現內容確實太多了,拆分為上、中、下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

為了便於理解,三維數組a[3][4][5]左下標優先存儲示例: 

左下標優先存儲:
    a[0][0][0]    a[0][0][1]    a[0][0][2]    a[0][0][3]    a[0][0][4]    a[0][1][0]    a[0][1][1]    a[0][1][2]    a[0][1][3]    a[0][1][4]
    a[0][2][0]    a[0][2][1]    a[0][2][2]    a[0][2][3]    a[0][2][4]    a[0][3][0]    a[0][3][1]    a[0][3][2]    a[0][3][3]    a[0][3][4]
    a[1][0][0]    a[1][0][1]    a[1][0][2]    a[1][0][3]    a[1][0][4]    a[1][1][0]    a[1][1][1]    a[1][1][2]    a[1][1][3]    a[1][1][4]
    a[1][2][0]    a[1][2][1]    a[1][2][2]    a[1][2][3]    a[1][2][4]    a[1][3][0]    a[1][3][1]    a[1][3][2]    a[1][3][3]    a[1][3][4]
    a[2][0][0]    a[2][0][1]    a[2][0][2]    a[2][0][3]    a[2][0][4]    a[2][1][0]    a[2][1][1]    a[2][1][2]    a[2][1][3]    a[2][1][4]
    a[2][2][0]    a[2][2][1]    a[2][2][2]    a[2][2][3]    a[2][2][4]    a[2][3][0]    a[2][3][1]    a[2][3][2]    a[2][3][3]    a[2][3][4]

按右下標作為主序存儲

任意一個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

為了便於理解,三維數組a[3][4][5]右下標優先存儲示例:

右下標優先存儲:
    a[0][0][0]    a[1][0][0]    a[2][0][0]    a[0][1][0]    a[1][1][0]    a[2][1][0]    a[0][2][0]    a[1][2][0]    a[2][2][0]    a[0][3][0]
    a[1][3][0]    a[2][3][0]    a[0][0][1]    a[1][0][1]    a[2][0][1]    a[0][1][1]    a[1][1][1]    a[2][1][1]    a[0][2][1]    a[1][2][1]
    a[2][2][1]    a[0][3][1]    a[1][3][1]    a[2][3][1]    a[0][0][2]    a[1][0][2]    a[2][0][2]    a[0][1][2]    a[1][1][2]    a[2][1][2]
    a[0][2][2]    a[1][2][2]    a[2][2][2]    a[0][3][2]    a[1][3][2]    a[2][3][2]    a[0][0][3]    a[1][0][3]    a[2][0][3]    a[0][1][3]
    a[1][1][3]    a[2][1][3]    a[0][2][3]    a[1][2][3]    a[2][2][3]    a[0][3][3]    a[1][3][3]    a[2][3][3]    a[0][0][4]    a[1][0][4]
    a[2][0][4]    a[0][1][4]    a[1][1][4]    a[2][1][4]    a[0][2][4]    a[1][2][4]    a[2][2][4]    a[0][3][4]    a[1][3][4]    a[2][3][4]

 


免責聲明!

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



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