稀疏矩陣的壓縮儲存
廣義表陣列和廣義表都可以看成是表中資料元素本身也是資料結構的線性表
對於n維陣列來說,每個元素都受到n個關係的約束,在每個關係中aj1j2…jn都會有乙個直接後繼,因此,對於單個關係而言,仍為線性關係。
n維陣列可以看為線性表的推廣且所有資料元素都屬於同一資料型別。
陣列一旦被定義,它的維度和維界就不再改變。因此,除了初始化和銷毀之外,陣列只有訪問元素和修改元素的操作
也就意味著不能插入和刪除
另外,陣列在計算機中儲存時有行優先的規定
對於二維陣列來說loc(i,j)=loc(0,0)+(b2*i+j)*l
(b2為第二維的長度,l為單個元素所佔儲存空間大小)
三維陣列按照 頁/行/列的順序儲存
對於n維陣列
loc(j1,j2,…,jn)=loc(0,0,…,0)+(b2x…xbnxj1+b3x…xbnxj2+…+bnxjn-1+jn)xl
特殊矩陣是指:值相同的元素或者非零元素在矩陣中的分布有一定規律的矩陣。
目的是為了節省儲存空間,對可以不儲存的元素(0或者對稱元素)不再儲存
常見的例子有對稱矩陣和三對角矩陣
對稱矩陣的壓縮
因為對稱矩陣中aij=aji
所以我們只儲存上三角/下三角矩陣(對角線+對角線上/下部分的元素)
儲存方法
將上/下三角矩陣存放到乙個n(n+1)/2長度的一維陣列中,稱為對稱矩陣的壓縮。
對應關係
若儲存下三角矩陣,則儲存元素aij全都有i>=j(1==j時,k=i(i-1)/2+j-1
當j>=i時,k=j(j-1)/2+i-1(即用aji對應了上三角的aij)
此時一位陣列sa[k]=aij,有了對應關係。
這樣的儲存方法也適用於三角矩陣
所謂的上(下)三角矩陣就是矩陣的下(上)三角(不包括對角線)中元素都為0或常數c的n階矩陣。
這樣只需要存上(下)三角中的元素再加乙個常數c即可壓縮三角矩陣。
三對角矩陣的壓縮
三對角矩陣除了主對角線和主對角線上、下相鄰的兩條對角線上的元素外,其他元素都為0。共有n+n-1+n-1=3n-2個要儲存的元素
三對角矩陣也是按照行優先的方式壓縮到一維陣列中
課本上這裡的 i,j又從零開始了…
對於aij
第i行前有3*i-1個非零元素
本行中第j列前有j-i+1個非零元素
所以k=2*i+j
所以b[2*i+j]=a[i][j]
而且,i=(k+1)/3向下取整、j=k-2i
稀疏矩陣0元素》非零元素且分布無規律的矩陣。
常使用矩陣的稀疏因子來判斷,δ=t/m*n(t為非零元素數,m,n為矩陣規格)
當δ<=0.05時,常認為是稀疏矩陣。
稀疏矩陣的儲存和特殊矩陣的儲存不同
特殊矩陣壓縮不需要儲存元素位置
而稀疏矩陣元素分布無規律,因此要儲存元素所在的位置
且還要儲存稀疏矩陣的規格m,n
三元組法
三元組的資料結構如下
class
tnode
;class
triple
;
因為c語言的陣列是行優先儲存,所以我們的三元組大都是以行序排列的三元組表示的稀疏矩陣的轉置演算法方法1.按照三元組中的列數進行轉置
對三元組掃瞄nu次,第k次對列數為k的項進行操作:將其行號列號互換,順序存到三元組中。
t.mu=nu;
t.nu=mu;
t.tu=tu;
if(t.tu)}}
}
時間複雜度為o(nu*tu)一般的矩陣轉置演算法的時間複雜度為o(munu)
當tu=munu時,為o(munu^2)
僅適用於tu
方法2.快速轉置運算
核心預先確定矩陣每一行第乙個非零元素在三元組中的位置,轉置時就可以直接放進去。
演算法就先不寫了,溜了~~
行邏輯連線的順序錶可方便進行稀疏矩陣乘法
十字鍊錶法適用於矩陣加法或減法運算。
顧名思義,廣義表是線性表的推廣(也稱為列表list)因此定義也相仿。
如下廣義表是n(>=0)個表元素組成的有限序列
記作ls=(a0,a1,a2,…,an-1)
其中ls為表名,ai為表元素,它可以是表(稱為子表),也可以是資料元素(稱為原子)
常常以大寫字母表示廣義表,小寫字母表示原子
n為表的長度,n=0的廣義表為空表
n>0時,表的第乙個元素稱為廣義表的表頭(head),除此之外,其他元素組成的表叫做廣義表的表尾(tail)
舉幾個栗子
a=()
a為空表,長度為0;
b=(e)
列表b只有乙個原子,長度為1
c=(a,(b,c,d))
列表c長度為2,兩個元素分別為原子a和子表(b,c,d)
d=(a,b,c)
列表d長度為3,3個元素都為子表
e=(a,e)
列表e長度為2,是乙個遞迴的表
f=( ( ) )
列表f長度為1,元素為空表
注意點
1.列表的元素可能是子表,子表的元素還可以是子表…因此,列表是乙個多層次的結構。
2.列表可以被其他列表共享。/ / d中有a,b,c三個子表
3.列表可以為乙個遞迴的表,即列表可以是本身的乙個子表。
4.任何乙個非空列表其表頭可能是原子,也可能是列表,但其表尾一定是列表
由於廣義表中資料元素可以具有不同的結構,所以很難用順序結構統一,所以一般使用鏈式儲存結構
需要兩種結點:
一是表結點,來表示列表。二是原子結點,來表示原子。
因為列表不空時可以分解成表頭和表尾,且根據一對確定的表頭和表尾可以確定唯一的列表
因此表結點需要由:標誌位、指示表頭的指標域、指示表尾的指標域三部分構成
而原子結點只需要:標誌位、值域兩部分即可。
typedef
enum
elemtag;
typedef
struct glnodeptr;};
}*glist;該方法的幾種情況
1.除空表的表頭指標為空外,任何非空列表,其表頭指標都指向乙個表結點。
且hp指向列表表頭,tp指向列表表尾(除非表尾為空,否則必為表結點)
2.容易分清列表中原子和子表所在層次
3.最高層表結點的個數即為表的長度
前面例子用這樣的方式表示
即廣義表中括號的重數
設非空廣義表為ls=(a1,a2,…,an)
則求ls的深度可分解為n個子問題,即求ai的深度
若ai是原子,深度為0,;若ai是廣義表,則繼續分解。
ls的深度為ai深度中最大值+1
空表的深度為1
廣義表(非線性結構)
廣義表 廣義表是一種非線性的資料結構,是一種較為簡單的資料結構,是線性表的擴充套件,是乙個由n個元素組成的序列。實現廣義表主要是利用遞迴,將其分為子問題來進行解決。下面是一些常見型別的廣義表 1 a 常稱為 空表 2 b a,b 一般的廣義表 3 c a,b,c,d 具有子表的廣義表 4 d a,b...
資料結構之 陣列和廣義表 複習題
第 4 章 陣列和廣義表 一 選擇題 1.將乙個a 1.100,1.100 的三對角矩陣,按行優先存入一維陣列b 1 298 中,a中元素a6665 即該元素下標i 66,j 65 在b陣列中的位置k為 b 供選擇的答案 a.198 b.195 c.197 2.二維陣列a的元素都是6個字元組成的串,...
線性表之廣義表
廣義表 lists,又稱列表 是一種非線性的資料結構,是線性表的一種推廣。定義 廣義表是n n 0 個元素a1,a2,ai,an的有限序列。其中 ai 或者是原子或者是乙個廣義表。廣義表通常記作 ls a1,a2,ai,an ls是廣義表的名字,n為它的長度。若ai是廣義表,則稱它為ls的子表。注意...