数据结构与算法分析:线性结构(1)

1.多项式的表示

     例:一元多项式及其运算

             一元多项式:f\left ( x \right )=a_{0}+a_{1}x^{2}+\cdot\cdot \cdot +a_{n-1}x^{n-1}+a_{n}x^{n}

              主要运算:多项式相加,相减,相乘

     ①顺序存储结构直接表示

         a\left [ i \right ] :项 x^{i}的系数 a_{i}

     ②顺序存储结构表示非零项

        用结构数组表示:把每个多项式看作为 \left (a_{i},i \right ) 二元组的集合

        例:P_{1}\left ( x \right )=9x^{12}+15x^{8}+3x^{2} 和 P_{2}\left ( x \right )=26x^{19}-4x^{8}-3x^{6}+82

    ③链表结构存储非零项

        链表中每个结点存储多项式的一个非零项,其中包括系数和指数两个数据域一个指针域。

        

coef expon link

       结构定义:

           typedef struct PolyNode* Polynominal;
           struct PolyNode{
                    int coef;
                    int expon;
                    Polynominal link;
                }

             

2.什么是线性表

     ①多项式表示问题的启示:

            同个问题可以有不同的存储方法

            有一类共性问题:有序线性序列和组织和管理

     ②线性表

 线性表的定义:         

        由同类数据元素构成的有序序列的线性结构

       线性表的抽象数据类型描述:

               数据对象集:n(>0)个元素构成有序序列

               操作集(主要):

                             1. List MakeEmpty()

                             2.ElementType FindKth(int K,List L)

                             3.int Find(ElementType X,List L)

                             4.void Insert(ElementType X,int i,List L)

                             5.void Delete(int i,List L)

                             6.int Length(List L)

     

  ③线性表的顺序存储实现:利用数组的连续空间顺序存放线性表的各元素

Data a_{1} a_{2} ···· a_{i} a_{i+1} ···· a_{n} ···· ---
           typedef struct LNode* List;
           struct LNode{
                  ElmentType Data[MAXSIZE];
                  int last;
             };
           struct LNode L;
           List PtrL;

     访问下标i的元素:L.Data[i] 或PtrL->Data[i]

     数组的长度:L.last+1 或 PtrL->last+1       

     主要操作的实现:

                      a.初始化:List MakeEmpty()

                   List MakeEmpty(){
                    List PtrL;
                    PtrL=(List)malloc(sizeof(struct LNode);
                    PtrL->last=-1;
                    return PtrL;
                    }

                       b.查找: int Find(ElementType X,List PtrL)

                       int Find(ElementType X,List PtrL){
                          int i=0;
                          while(i<PtrL->last&&Ptrl->Data[i]!=X)
                               i++;
                          if(i>PtrL->last)
                              return -1;
                          else return i;
                         }

                      c.插入:void Insert(ElementType X,int i,List PtrL)

         void Insert(ElementType X,int i,List PtrL){
             int j;
             if(PtrL->last==MaxSize-1){
                 printf("表满");
                 return;
             }
            if(i<1||i>PtrL->last+2){
                printf("位置不合法");
                return;
             }
            for(j=PtrL->last;j>=i-1;j--)
                 PtrL->Data[j+1]=PtrL->Data[j];
            PtrL[i-1]=X;
            PtrL->last++;
            return;
         }

                      d.删除:void Delete(int i,List PtrL)

                    void Delete(int i,List PtrL){
                      int j;
                      if(i<1||i>PtrL->last+1){
                          printf("不存在第%d个元素",i);
                          return;
                       }
                      for(j=i;j<=PtrL->last;j++)
                         PtrL[j-1]=PtrL[j];
                      PtrL->last--;
                      return;
                     }

④线性表的链式存储实现

     不要求逻辑上相邻的两个元素物理上也相邻,通过“链”建立起数据元素之间的逻辑关系

        typedef struct LNode* List;
        struct LNode{
           ElementType Data;
           List Next;
        };
        struct LNode L;
        List PtrL;

    主要操作的实现:

                      a.求表长:int Length(List PtrL)

              int Length(List PtrL){
               List p=PtrL;
               int j=0;
               while(p){
                 p=p->next;
                 j++;
                }
                return j;
              }

                      b.查找

                          (1)a按序号查找:FindKth

                List FindKth(int K,List PtrL){
                   List p=PtrL;
                   int i=1;
                   while(p!=NULL&&i<K){
                       p=p->next;
                       i++;
                   }
                   if(i==K) 
                      return p;
                   else 
                      return NULL;
                }
                       

                          (2)按值查找:Find

               List Find(ElementType X,List PtrL){
                  List p=PtrL;
                  while(p!=NULL&&p->data!=X)
                     p=p->next;
                  return p;
                }

                      c.插入:

                          (1) 先构造一个结点,用s指向

                          (2) 再找到链表的第i-1个结点,用p指向

                          (3) 然后修改结点,插入结点(s->next=p->next;p->next=s)

       List Insert(ElementType X,int i;List PtrL){
           List p,s;
           if(i==1){
            s=(List)malloc(sizeof(struct LNode);
            s-Data=X;
            s->next=PtrL;
            return s;
            }
           p=FindKth(i-1,PtrL);
           if(p==NULL){
               printf("参数i错");
               return NULL;
           }
           else{
               s=(List)malloc(sizeof(struct LNode));
               s->Data=X;
               s->next=p->next;
               p->next=s;
               return PtrL;
             }
           }

                      d.删除

                          (1) 先找到链表第i-1个结点,用p指向 

                          (2) 再用指针s指向要删除结点(p的下一个节点)

                          (3) 然后修改指针,删除s所指向结点(p->next=s->next)

                          (4)  最后释放s所指向结点的空间 (free(s))

       List Delete(int i,List PtrL){
         List p,s;
         if(i==1){
             s=PtrL;
             if(PtrL==NULL)
               PtrL=PtrL->next;
             else 
               return NULL
             free(s);
             return PtrL;
          }
        p=FindKth(i-1,PtrL);
        if(p==NULL){
           printf("第%d个结点不存在",i-1);
           return NULL;
        }else if(p->next==NULL){
            printf("第%d个结点不存在",i);
            return NULL;
        }else{
             s=p->Next;
             p->next=s->next;
             free(s);
             return PtrL;
         }

           

⑤广义表

     例:给定二元多项式 P\left ( x,y\right )=9x^{12}y^{2}+4x^{12}+15x^{8}y^{3}-x^{8}y+3x^{2}

             可以表示为关于x的一元多项式:P\left ( x,y\right )=\left(9y^{2}+4\right )x^{12}+\left( 15y^{3}-y\right )x^{8}+3x^{2}

广义表定义:

        是线性表的推广

        广义表中,元素不仅可以为单元素还可以是另一个广义表

         typedef struct GNode* GList;
         struct GNode{
               int Tag; /* 标志域:0表示结点是单元素,1表示结点是广义表 */
               union{   /* 子表指针域SubList与单元素数据Data复用 */
                ElementType Data;
                GList SubList;    
              }URegion;
                GList Next;
          };

    

Tag

Data

————

SubList

Next

⑥多重链表

多重链表的特性:

      多重链表中的结点的指针域有多个;

      但包含两个指针域的链表不一定是多重链表(如双向链表)

      例:采用一种典型的多重链表——十字链表来存储稀疏矩阵

              结点的数据域:行坐标Row,列坐标Col,数值Value;

             每个结点通过两个指针域,把同行、同列穿起来

                   行指针Right

                   列指针Down 

             用一个是标识域Tag区分头结点和非0元素结点

            头结点的标识值为“Head”,矩阵非0元素节点的标识值为“Term”

          

(a)结点的总体结构
   Tag      
Down URegion Right
(b)矩阵的非0元素结点
  Term  
Down

Row   |  Col

——————

   Value

Right

                                          

(c)头结点
                Head  
Down Next Right

猜你喜欢

转载自blog.csdn.net/rachel9798/article/details/82820151
今日推荐