稀疏矩陣

一、稀疏矩陣的定義

  對於那些零元素數目遠遠多於非零元素數目,並且非零元素的分佈沒有規律的矩陣稱爲稀疏矩陣(sparse)。
  人們無法給出稀疏矩陣的確切定義,一般都只是憑個人的直覺來理解這個概念,即矩陣中非零元素的個數遠遠小於矩陣元素的總數,並且非零元素沒有分佈規律。
    

二、稀疏矩陣的壓縮存儲

  由於稀疏矩陣中非零元素較少,零元素較多,因此可以採用只存儲非零元素的方法來進行壓縮存儲。
  由於非零元素分佈沒有任何規律,所以在進行壓縮存儲的時侯需要存儲非零元素值的同時還要存儲非零元素在矩陣中的位置,即非零元素所在的行號和列號,也就是在存儲某個元素比如aij的值的同時,還需要存儲該元素所在的行號i和它的列號j,這樣就構成了一個三元組(i,j,aij)的線性表。
  三元組可以採用順序表示方法,也可以採用鏈式表示方法,這樣就產生了對稀疏矩陣的不同壓縮存儲方式。

a、稀疏矩陣的順序實現

  若把稀疏矩陣的三元組線性表按順序存儲結構存儲,則稱爲稀疏矩陣的三元組順序表。
  順序表中除了存儲三元組外,還應該存儲矩陣行數、列數和總的非零元素數目,這樣才能唯一的確定一個矩陣。

    

  順序存儲結構存儲三元組線性表的C#代碼如下:

代碼
    struct tupletype<T>
    {
        public int i;//行號
        public int j;//列號
        public T v; //元素值
        public tupletype(int i, int j, T v)
        {
            this.i = i;
            this.j = j;
            this.v = v;
        }
    }
    class spmatrix<T>
    {
        int MAXNUM;//非零元素的最大個數
        int md;//行數值
        int nd;//列數值
        int td;//非零元素的實際個數
        tupletype<T>[] data;//存儲非零元素的值及一個表示矩陣行數、列數和總的非零元素數目的特殊三元組
    }
b、稀疏矩陣的十字鏈表實現

    十字鏈表結點分爲三類 :
  表結點,它由五個域組成,其中i和j存儲的是結點所在的行和列,right和down存儲的是指向十字鏈表中該結點所有行和列的下一個結點的指針,v用於存放元素值。
  行頭和列頭結點,這類結點也有域組成,其中行和列的值均爲零,沒有實際意義,right和down的域用於在行方向和列方向上指向表結點,next用於指向下一個行或列的表頭結點。
  總表頭結點,這類結點與表頭結點的結構和形式一樣,只是它的i和j存放的是矩陣的行和列數。

    

  十字鏈表可以看作是由各個行鏈表和列鏈表共同搭建起來的一個綜合鏈表,每個結點aij既是處在第i行鏈表的一個結點,同時也是處在第j列鏈表上的一個結點,就你是處在十字交叉路口上的一個結點一樣,這就是十字鏈表的由來。
  十字鏈表中的每一行和每一列鏈表都是一個循環鏈表,都有一個表頭結點。
    
三、稀疏矩陣的實現

  矩陣運算通常包括矩陣轉置、矩陣加、矩陣乘、矩陣求逆等。這裏僅討論最簡單的矩陣轉置運算算法。
  矩陣轉置運算是矩陣運算中最重要的一項,它是將m×n的矩陣變成另外一個n×m的矩陣,使原來矩陣中元素的行和列的位置互換而值保持不變,即若矩陣N是矩陣M的轉置矩陣,則有:M[i][j]=N[j][i] (0≤i≤m-1,0≤j≤n-1)。

三元組表表示轉置矩陣的具體方法是:
  第一步:根據M矩陣的行數、列數和非零元總數確定N矩陣的列數、行數和非零元總數。
  第二步:當三元組表非空(M矩陣的非零元不爲0)時,對M中的每一列col(0≤col≤n-1),通過從頭至尾掃描三元組表data,找出所有列號等於col的那些三元組,將它們的行號和列號互換後依次放人N的data中,即可得到N的按行優先的壓縮存貯表示。

代碼
    class spmatrix<T>
    {
        int MAXNUM;//非零元素的最大個數
        int md;//行數值
        int nd;//列數值
        int td;//非零元素的實際個數
        tupletype<T>[] data;//存儲非零元素的值及一個表示矩陣行數、列數和總的非零元素數目的特殊三元組
        public int Md
        {
            get
            {
                return md;
            }
            set
            {
                md = value;
            }
        }
        public int Nd
        {
            get
            {
                return nd;
            }
            set
            {
                nd = value;
            }
        }
        public int Td
        {
            get
            {
                return td;
            }
            set
            {
                td = value;
            }
        }
        //三元組表的data屬性
        public tupletype<T>[] Data
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }
        //初始化三元組順序表
        public spmatrix() { }
        public spmatrix(int maxnum, int md, int nd)
        {
            this.MAXNUM = maxnum;
            this.md = md;
            this.nd = nd;
            data = new tupletype<T>[MAXNUM];
        }
        //設置三元組表元素的值
        public void setData(int i, int j, T v)
        {
            data[td] = new tupletype<T>(i, j, v);
            td++;
        }
        //矩陣轉置算法
        public spmatrix<T> Transpose()
        {
            spmatrix<T> N = new spmatrix<T>();
            int p, q, col;
            N.MAXNUM = MAXNUM;
            N.nd = md;
            N.md = nd;
            N.td = td;
            N.data = new tupletype<T>[N.td];
            if (td != 0)
            {
                q = 0;//控制轉置矩陣的下標
                for (col = 0; col < nd; col++)//掃描矩陣的列
                {
                    for (p = 0; p < td; p++)//p控制被轉置矩陣的下標
                    {
                        if (data[p].j == col)
                        {
                            N.data[q].i = data[p].j;
                            N.data[q].j = data[p].i;
                            N.data[q].v = data[p].v;
                            q++;
                        }
                    }
                }
            }
            return N;
        }

 


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zhongjiekangping/archive/2010/05/13/5585933.aspx

發佈了20 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章