zoukankan      html  css  js  c++  java
  • 广义表(线性表的推广)

    广义表的定义

      广义表是线性表的推广。 广义表一般记作LS=(d0,d1,...dn-1)
      其中,LS是广义表(d1,d2,...dn)的名称,n是它的长度.在线性表的定义中,ai(1<=i<=n)只限于是单个元素.而在广义表的定义中,di可以是单个元素。也可以是广义表,分别称为广义表LS的单元素和子表。习惯上,用大写字母表示广义表的名称,用小写字母表示单元素。当广义表LS非空时,称第一个元素d0为表头(Head),称其余元素组成的表(d1,d2,...dn-1)是LS的表尾(Tail)。
      显然,广义表的定义是一个递归的定义,因为在描述广义表时又用到了广义表的概念。下面列举一些广义表的例子。
      1) A=( ); A是一个空表,它的长度为0。
      2) B=( e );  广义表B只有一个单元e,B的长度为1。
      3) C=( a,( b,c,d ) ); 广义表C的长度为2,两个元素分别为单元素a和子表( b,c,d )。
      4) D=( A,B,C ); 广义表D的长度为3,三个元素都是列表。显然,将子表的值代入后,则有D=( ( ),( e ), ( a,( b,c,d ) ) )。
      5) E=( a,E ); 这是一个递归的表,它的长度为2。E相当于一个无限的广义表E=( a,( a,( a......) ) )。
      

      从上述定义和例子可推出广义表的三个重要结论:
      1)  广义表的元素可以是子表,而子表的元素还可以是子表,...。
      2)  广义表可为其他广义表所共享。
      3)  广义表可以是一个递归的表,即广义表也可以是其本身的一个子表。

    广义表的深度

      一个广义表的深度是指该广义表展开后所含括号的层数。
      例如,A=(b,c)的深度为1,B=(A,d)的深度为2,C=(f,B,h)的深度为3。

    广义表的存储结构

      由于广义表的元素类型不一定相同,因此,难以用顺序结构存储表中元素,通常采用链接存储方法来存储广义表中元素,并称之为广义链表。
      采用链式存储结构,每个数据元素可用一个结点表示:
      · (1)表结点,用以表示子表
      · (2)元素结点,用以表示单元素

    第一种表示

    用C语言描述结点的类型如下:

    1 typedef struct node
    2 {
    3 int tag;
    4 union{struct node *hp,*tp;
    5 char data;
    6 }dd;
    7 }NODE;

    第二种表示 

    用C语言描述结点的类型如下:

    1 typedef struct node
    2 {
    3 int tag;
    4 union{struct node *hp;
    5 char data;
    6 }dd;
    7 struct node *tp;
    8 }NODE;

    广义表的递归算法

    一、求广义表的深度

    深度公式:
    (1)maxdh(p)=0 当p->tag=1

    (2)maxdh(p)=1 当空表(p->tag=1&&p->dd.sublist=NULL)

    (3)maxdh(p)=max(maxdh(p1),...,maxdh(pn))+1 其余情况

    其中p=(p1,p2,...,pn)

     1 int depth(NODE *p) /*求表的深度函数 */
     2 {
     3 int h,maxdh;
     4 NODE *q;
     5 if(p->tag==0) return(0);
     6 else 
     7 if(p->tag==1&&p->dd.sublist==NULL) return 1;
     8 else
     9 {
    10 maxdh=0;
    11 while(p!=NULL)
    12 { 
    13 if(p->tag==0) h=0;
    14 else
    15 {q=p->dd.sublist;
    16 h=depth(q);
    17 }
    18 if(h>maxdh)maxdh=h;
    19 p=p->link;
    20 }
    21 return(maxdh+1);
    22 }
    23 }

    二、求原子结点个数

    原子结点个数公式:

    (1)f(p)=0 当p=NULL

    (2)f(p)=1+f(p->link) 当p->tag=0

    (3)f(p)=f(p->dd.sublist)+f(p->link) 当p->tag=1

     1 int count(NODE *p) /*求原子结点的个数函数 */
     2 {
     3 int m,n;
     4 if(p==NULL) return(0);
     5 else
     6 {
     7 if(p->tag==0) n=1;
     8 else 
     9 n=count(p->dd.sublist);
    10 if(p->link!=NULL)
    11 m=count(p->link);
    12 else m=0;
    13 return(n+m);
    14 }
    15 }

    三、求原子结点数据域之和

    原子结点数据域之和公式:

    (1)f(p)=0 当p=NULL

    (2)f(p)=p->data+f(p->link) 当p->tag=0

    (3)f(p)=f(p->dd.sublist)+f(p->link) 当p->tag=1

     1 int sum(NODE *p) /*求原子结点数据域之和函数 */
     2 {
     3 int m,n;
     4 if(p==NULL) return(0);
     5 else
     6 {
     7 if(p->tag==0) n=p->dd.data-’0’;
     8 else 
     9 n=sum(p->dd.sublist);
    10 if(p->link!=NULL)
    11 m=sum(p->link);
    12 else m=0;
    13 return(n+m);
    14 }
    15 }
  • 相关阅读:
    B树,B+树
    中断
    死锁
    无锁队列
    Cookie和Session
    分布式系统一致性
    c++ 标准库迭代器失效
    html5 app图片预加载
    html5 手机APP计算高度问题
    html5 750 REM JS换算方法
  • 原文地址:https://www.cnblogs.com/Eason-S/p/5396822.html
Copyright © 2011-2022 走看看