5.19 PROC  saddlepoint(a:array2tp);

           {amn列的二维数组,本算法求所有马鞍点}

           {b是一维数组,存放一行中可能的马鞍点的列值,k记相等值个数}

           {c是一维数组,存放某列可能马鞍点的行值,kk记相等值个数}

      FOR  i:=1 to m  DO

         [ min:=a[i,1]; {最小值初始化}

          b[1]:=1; k:=1

          FOR j:=2 to n DO {找每一行中的最小值}

             IF a[i,j]<min THEN [b[1]:=j; min:=a[ i,j]; k:=1]  {重新确定最小值}

                ELSE IF a[ i,j]=min THEN [b[k+1]:=j; k:=k+1] {有相等的最小值}

          FOR jj:=1 TO k DO {I行有k个相等的最小值}

             [ j:=b[jj]; max:=a[1,j] ; kk:=1;  c[1]:=I; {a[i,j]是否是马鞍点}

              FOR ii:=2 to m DO {找第j列的最大值}

                 IF a[ii,j]>max THEN [c[1]:=ii; max:=a[ii,j]; kk:=1]  {重新确定最大值}

                    ELSE IF a[ii,j]=max THEN [c[kk+1]:=ii; kk:=kk+1] {有相等的最大值}

              IF  max=min  THEN  {有可能是马鞍点}

                 FOR ii:=1 TO kk DO   {kk个相等的最大值哪个是马鞍点}

                    IF  c[ii]= i  THEN WRITE(‘马鞍点 ’,i:4,j:4,a[ i,j]:4)

             ]  {END OF  ‘FOR jj=1  TO  k  DO’}

           ]   { END OF  ‘FOR  i =1 to m DO’ }

   ENDP;

   解法2: 若矩阵中元素值互不相同,则第i行只一个最小值,记下列号j;

          然后在第j列查最大值,记下其行号ii, i=ii,a[ i,j]是马鞍点.

 

  改进: 在第j列求最大值时,可用WHILE 循环,一但某值大于最小值min, 即可

        退出循环, 该点不是马鞍点. 程序段如下:

        FOR jj:=1 TO k DO {I行有k个相等的最小值}

             [ j:=b[jj];  ii:=1;  flag:=true;  kk:=0;  c[1]:= i; {a[ii,j]是否是马鞍点}

              WHILE  (ii<=m) AND flag  DO {找第j列的最大值}

                 IF a[ii,j]>min THEN flag:=false

                    ELSE IF a[ii,j]=min THEN [c[kk+1]:=ii; kk:=kk+1] {有相等的最大值}

              IF  kk<>0  THEN  {有可能有马鞍点}

                 FOR ii:=1 TO kk DO   {kk个相等的最大值哪个是马鞍点}

                    IF  c[ii]= i  THEN WRITE(‘马鞍点 ’,i:4,j:4,a[ i,j]:4)

             ]  {END OF  ‘FOR jj=1  TO  k  DO’}

解法2: 先将矩阵每行的最小值存入 row 一维数组,将每列的最大值存入col 一维数组,

       进行两层循环,a[ i,j]=row[ i]=col[j], a[ i,j] 为马鞍点.

       FOR I:=1 TO m  DO

           FOR j:=1 TO n  DO

               IF a[ i,j]=row[ i] AND a[ i,j]=col[ j] THEN WRITE(‘马鞍点 ’,i:4,j:4,a[ i,j]:4)

      {时间复杂度O(3*(m*n)) ,  当马鞍点很多时适宜}


 

5.21  TYPE link=^matnode;

       feature=(headnode,element);

       matnode=RECORD

                 i,j:integer;     Right,down:link;

                 Case feature OF

                     Headnode:( next:link);  Element: (v:elemtp);

                 END;

PROC  addmatrix(var ha:link; hb:link);

 {ha,hb 分别是以十字链表为存储结构的稀疏矩阵的头指针,本算法将两矩阵加,}

 {结果放在以ha为头指针的稀疏矩阵中}

 ca:=ha^.next; cb:=hb^.next;  {ca,cb 分别指向第一行列表头}

 WHILE  (ca<>ha)  AND  (cb<>hb )  DO  
        [ pa:=ca^.right; pb:=cb^.right;  {pa,pb
分别指向该行第一非0元素}

     IF pb^.j=0 THEN  [ ca:=ca^.next;  cb:=cb^.next ];

        {B的该行无非0 元素, ca,cb各指向下一行}

     WHILE  pb^.j<>0  DO  {处理一行}

       [ qa:=pa;  {qa 为前驱结点}

        CASE

          (pa^.j<pb^.j) AND (pa^.j<>0) :qa:=pa; pa:=pa^.right;{qa^已是结果中的一项}

          (pa^.j>pb^.j) OR (pa^.j=0) : {pb^的列号小,是结果中的一项}

            [ p:=pb; qa^.right:=p; p^.right:=pa;  {pb^ 结点插入pa^所在行行中}

             pp:=cpa[pb^.j];  {cpa,cpbA,B 的行列表头指针数组}

             WHILE(pp^.down<>cpa[pb^.j]AND(pp^.down^.i<pa^.i)DO pp:=pp^.down;

              p^.down:=pp^.down; pp^.down:=p; pb^ 结点链入pb^.j所在列中}

              pb:=pb^.right;

             ]

            pa^.j=pb^.j: pa^.v:=pa^.v+pb^.v;  [ IF pa^.v=0 THEN {删除该结点}

                                   [ qa^.right:=pa^.right;  {行中删除}

                                    p:=cpa[pb^.j];

                                    WHILE p^.down<>pa  DO  p:=p^.down;

                                    p^.down:=pa^.down;  {列中删除}

                                   ]

                                   pa:=pa^.right; pb:=pb^.right;

                                 ] ; {END OF IF pa^.v=0 }

          ENDC;   { END OF CASE}

       ] ;  {END OF WHILE }

    ca:=ha^.next; cb:=hb^.next;  {ca,cb 分别指向下一行列表头}

]  { END OF WHILE (ca<>ha) AND (cb<>hb)  ]


 

5.25

  PROC addmatrix(VAR b3:ARRAY[1..m,1..n] OF 0..1;

                 VAR v3:ARRAY[1..maxlen] OF integer;

                 b1,b2:ARRAY[1..m,1..n] OF 0..1; v1, v2:ARRAY[1..maxlen] OF integer);

                     {b1,b2是稀疏矩阵A1,A20..1矩阵}

                     (稀疏矩阵中非0元在0..1矩阵的相应位置用1表示),}

                     {v1,v2是稀疏矩阵A1,A2的非0元以行序为主存储的一维数组;}

                     {本算法实现矩阵A1,A2相加,结果按上述约定存于b3,v3}

         pb1:=pb2:=pb3:=0;  {pb1,pb2,pb3分别指向v1,v2,v3中当前元素位置}

         FOR  I: =1 TO m  DO

             FOR j :=1 TO n  DO

                 IF b1[ I,j] =1  OR b2[I,j]=1

                     THEN [  IF b1[I,j]=1

                                 THEN [ pb1:=pb1+1; s1:=v1[pb1]

                                 ELSE  s1:=0;

                              IF b2[I,j]=1

                                 THEN [ pb2:=pb2+1; s2:=v2[pb2]

                                 ELSE  s2:=0;

                              IF s1+s2<>0

                                 THEN [ pb3:=pb3+1; v3[pb3]:=s1+s2;b3[I,j]:=1

                                 ELSE  b3[I,j]::=0;

                           ]

   ENDP;

 

     讨论: 若以相加作为估计复杂度的主要操作, 则复杂度为O(n), n为两个稀疏矩阵中非0 元素之和.