1. 程式人生 > >數據結構29:廣義表的長度和深度

數據結構29:廣義表的長度和深度

clu char contain ons 例如 malloc nio 廣義表的深度 wrap

廣義表的長度

通過前一節對廣義表的介紹,例子中給出了幾個廣義表的長度。例如:空表的長度為 0,只含有一個原子的廣義表長度為 1,等等。

廣義表的長度指的是廣義表中數據元素的數量。這裏需要指明的是,一個廣義表中,一個原子算做是一個元素,一個子表也只算做一個元素。

在 LS = (a1,a2,…,an) 中,ai表示原子或者子表, LS 的長度為 n。

廣義表的深度

廣義表的深度,指的是廣義表中括號的重數。
例如:C=(a,(b,c,d)): 技術分享圖片
圖1 廣義表C的深度
圖1中,從前往後數左括號的數量就是廣義表C的深度,為2;也可以從右往左數右括號的數量(紅色)。

求解廣義表的深度

求廣義表的深度之前,首先要將廣義表用某個數據結構表示出來,在前邊學習廣義表時,介紹了兩種表示廣義表的方法。這裏采用的方法是第一種。

表示結構為:(拿廣義表C為例) 技術分享圖片 廣義表第一節中有具體實現的代碼,實現函數為:creatGlist(Glist C)。這裏不再過多介紹。 求廣義表深度的算法用到的是遞歸的思想,解題思路是:

  1. 從廣義表 C 的開頭位置,一次遍歷表中每個數據元素:當遍歷對象為原子時,返回原子的深度為 0 ;遍歷對象為表 C 的子表時,繼續遍歷子表中的數據元素。
  2. 遞歸的出口有兩個:當遍歷對象為原子時,返回 0 ;遍歷對象為空表時,返回 1 (空表的深度為 1 );
  3. 設置一個初始值為 0 的整形變量 max ,用 max 和遍歷過程中返回的整形數值進行比較,取大的那一個,知道程序結束,max + 1就是廣義表的深度。

實現代碼為:
int GlistDepth(Glist C)
{   
//如果表C為空表時,直接返回長度1;   if (!C)
  {     
return 1;   }   //如果表C為原子時,直接返回0;   if (C->tag == 0)
  {     
return 0;   }   int max = 0;  //設置表C的初始長度為0;   for (Glist pp=C; pp; pp=pp->ptr.tp)
  {     
int dep = GlistDepth(pp->ptr.hp);     if (dep>max)
    {       max
= dep;  //每次找到表中遍歷到深度最大的表,並用max記錄     }   }   //程序運行至此處,表明廣義表不是空表,由於原子返回的是0,而實際長度是1,所以,此處要+1;   return max+1; }

完整代碼演示
#include <stdio.h>
#include <stdlib.h>
typedef struct GLNode
{   
int tag;  //標誌域   union
  {     
char atom;  //原子結點的值域     struct
    
{       struct GLNode *hp, *tp;     }ptr;  //子表結點的指針域,hp指向表頭;tp指向表尾   }; }*Glist, GNode;
Glist creatGlist(Glist C)
{   
//廣義表C   C=(Glist)malloc(sizeof(GNode));   C->tag = 1;   //表頭原子‘a’   C->ptr.hp = (Glist)malloc(sizeof(GNode));   C->ptr.hp->tag = 0;   C->ptr.hp->atom = a;   //表尾子表(b,c,d),是一個整體   C->ptr.tp = (Glist)malloc(sizeof(GNode));   C->ptr.tp->tag = 1;   C->ptr.tp->ptr.hp = (Glist)malloc(sizeof(GNode));   C->ptr.tp->ptr.tp = NULL;   //開始存放下一個數據元素(b,c,d),表頭為‘b’,表尾為(c,d)   C->ptr.tp->ptr.hp->tag = 1;   C->ptr.tp->ptr.hp->ptr.hp = (Glist)malloc(sizeof(GNode));   C->ptr.tp->ptr.hp->ptr.hp->tag = 0;   C->ptr.tp->ptr.hp->ptr.hp->atom = b;   C->ptr.tp->ptr.hp->ptr.tp = (Glist)malloc(sizeof(GNode));   //存放子表(c,d),表頭為c,表尾為d   C->ptr.tp->ptr.hp->ptr.tp->tag = 1;   C->ptr.tp->ptr.hp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(GNode));   C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag = 0;   C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom = c;   C->ptr.tp->ptr.hp->ptr.tp->ptr.tp = (Glist)malloc(sizeof(GNode));   //存放表尾d   C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag = 1;   C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(GNode));   C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag = 0;   C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->atom = d;   C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp = NULL;
  
return C; }
//求廣義表的深度,遞歸調用 int GlistDepth(Glist C)
{   
if (!C)
  {     
return 1;   }   if (C->tag == 0)
  {     
return 0;   }   int max = 0;   for (Glist pp=C; pp; pp=pp->ptr.tp)
  {     
int dep = GlistDepth(pp->ptr.hp);     if (dep>max)
    {       max
= dep;     }   }   return max+1; }
int main(int argc, const char *argv[])
{   Glist C
= creatGlist(C);   printf("%d", GlistDepth(C));
  
return 0; }
運行結果:
2

數據結構29:廣義表的長度和深度