廣義表的建立與一般操作C\C++

廣義表的建立與一般操作C\C++

一、廣義表的概念
        廣義表是線性表的推廣,但線性表的元素僅限於原子項,原子作爲結構上不可分割的成分,它可以是一個數或一個結構,若放鬆對錶元素的這種限制,允許它們具有自身獨立類型結構,就產生了廣義表的概念。
       廣義表是n(n>=0)個數據元素a1,a2,......ai,......,an的有序序列,一般記作:
                                                                                                                                    ls = (a1,a2 ,........,ai, ...an)
      其中:ls是廣義表的名稱,n是它的長度。
二、廣義表的數據結構
A = ()
B = (e)
C = (a,(b,(c,d)))
D = ((),B,C)
E = (a,E)
F = (())

圖中爲廣義表的頭尾表示法
頭尾表示法的存儲結構:
typedef enum {ATOM , LIST} Elemtag ;
typedef struct node
{
    Elemtag tag ; //用以標記是單個元素或廣義表
    union
    {
        datatype data ;
        struct
        {
            struct node *hp , *tp ; //指向廣義表頭節點和尾節點的指針
        } ptr ;
    };
} GLNode , *GList ;
孩子兄弟表示法的存儲結構:
typedef enum {ATOM , LIST} ELemtag ;
typedef struct GLENode{
  Elemtag tag ;
 union{
  datatype data ;
  struct GLENode *hp ;
  }
struct GLENode *tp ;
} *EGList ;
三、廣義表的操作
1、廣義表的取頭、取尾操作
/*
 *廣義表的取頭操作
 */
GList GetHead(GList ls)
{
    GList list = NULL ;
    if(ls->tag == 1)
    {
        list = ls->ptr.hp ;
    }
    return list ;
}
/*
 *廣義表的取尾操作
 */
GList GetTail(GList ls)
{
    GList list = NULL ;
    if(ls->tag == 1)
    {
        list = ls->ptr.tp ;
    }
    return list ;
}
2、建立廣義表的存儲結構
/*
 *將字符串分爲表頭和表尾字符串
 */
void server(char *hsub , char *s)
{
   int i , k ;
   for(i = 0 , k = 0 ; i < strlen(s) ; i++)
   {
       if(s[i] == '(')
       {
           k++;
       }
       if(s[i] == ')')
       {
           k--;
       }
       if(s[i] == ',' && k == 0)
       {
           break ;
       }
   }
   if(i < strlen(s))
   {
       substr(s , hsub , 1 , i) ;
       substr(s , s , i + 2 , strlen(s) - i - 1) ;
   }
   else
   {
       substr(s , hsub , 1 ,strlen(s)) ;
       s[0] = '\0' ;
   }
}
/*
 *建立廣義表的存儲結構
 */
int CreateGList(GList *ls , char *s)
{
    GLNode *p , *q ;
    char hsub[MAXSIZE] ;
    //字符串爲空時,廣義表爲空
    if(s == NULL)
    {
        *ls = NULL ;
    }
    else
    {
        if(!(*ls = (GList)malloc(sizeof(GLNode))))
        {
            return 0 ;
        }
        //字符長度爲1時,廣義表爲單個元素
        if(strlen(s) == 1)
        {
            (*ls)->tag = 0 ;
            (*ls)->data = *s ;
        }
        else
        {
            substr(s , s , 2 , strlen(s) - 2) ; //去掉最外層括號;
            p = (*ls) ;
            p->tag = 1 ;
            do
            {
                server(hsub , s) ; //獲取頭節點
                CreateGList(&(p->ptr.hp) , hsub) ;
                q = p ;
                if(*s != '\0')
                {
                    p = (GList)malloc(sizeof(GLNode)) ;
                    p->tag = 1 ;
                    q->ptr.tp = p ;
                }
                else
                {
                    p->ptr.tp = NULL ;
                }
            }while(*s != '\0') ;
        }
    }
    return 1 ;
}
3、以表頭、表尾建立廣義表
/*
 *以表頭和表尾建立廣義表
 */
int Merge(GList l1 , GList l2 , GList *ls)
{
    if(!((*ls) = (GList)malloc(sizeof(GLNode))))
    {
        return 0 ;
    }
    (*ls)->tag = 1 ;
    (*ls)->ptr.hp = l1 ;
    (*ls)->ptr.tp = l2 ;
    return 1 ;
}
4、求廣義表的長度
/*
 *取得廣義表的長度
 */
int Depth(GList ls)
{
    GList p ;
    int max , depth ;
    if(ls == NULL)
    {
        return 1 ; //空表長度爲1
    }
    if(ls->tag == 0)
    {
        return 0 ; //單元素長度爲0
    }
    for(max = 0 , p = ls->ptr.tp; p ; p = p->ptr.tp)
    {
        depth = Depth(p) ;
        if(depth > max)
        {
            max = depth ;
        }
    }
    return max + 1 ;
}
5、複製廣義表
/*
 *進行廣義表的複製
 */
int CopyGList(GList ls , GList *ls1)
{
    if(ls == NULL)
    {
        (*ls1) = NULL ;
    }
    else
    {
        if(!((*ls1)=(GList)malloc(sizeof(GLNode))))
        {
            return 0 ;
        }
        if(ls->tag == 0)
        {
            (*ls1)->tag = 0 ;
            (*ls1)->data = ls->data ;
        }
        else
        {
            (*ls1)->tag = 1 ;
            CopyGList(ls->ptr.hp , &((*ls1)->ptr.hp)) ;
            CopyGList(ls->ptr.tp , &((*ls1)->ptr.tp)) ;
        }
    }
}
四、測試的全部代碼
/*
 *操作均是建立在關於建立在頭尾指針的廣義表上
 */
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define MAXSIZE 100
/*
 *定義廣義表節點的存儲結構
 */
typedef char datatype ;
typedef enum {ATOM , LIST} Elemtag ;
typedef struct node
{
    Elemtag tag ; //用以標記是單個元素或廣義表
    union
    {
        datatype data ;
        struct
        {
            struct node *hp , *tp ; //指向廣義表頭節點和尾節點的指針
        } ptr ;
    };
} GLNode , *GList ;
/*
 *進行字符串的裁剪,s爲被裁剪的對象
 */
void substr(char *s , char *sub , int startIndex , int len)
{
   int i ;
   for(i = 1 ; i < startIndex ; s++ , i++) ;
   for(i = 0 ; i < len ; i++)
   {
       sub[i] = s[i] ;
   }
   sub[len] = '\0' ;
}
/*
 *將字符串分爲表頭和表尾字符串
 */
void server(char *hsub , char *s)
{
   int i , k ;
   for(i = 0 , k = 0 ; i < strlen(s) ; i++)
   {
       if(s[i] == '(')
       {
           k++;
       }
       if(s[i] == ')')
       {
           k--;
       }
       if(s[i] == ',' && k == 0)
       {
           break ;
       }
   }
   if(i < strlen(s))
   {
       substr(s , hsub , 1 , i) ;
       substr(s , s , i + 2 , strlen(s) - i - 1) ;
   }
   else
   {
       substr(s , hsub , 1 ,strlen(s)) ;
       s[0] = '\0' ;
   }
}
/*
 *建立廣義表的存儲結構
 */
int CreateGList(GList *ls , char *s)
{
    GLNode *p , *q ;
    char hsub[MAXSIZE] ;
    //字符串爲空時,廣義表爲空
    if(s == NULL)
    {
        *ls = NULL ;
    }
    else
    {
        if(!(*ls = (GList)malloc(sizeof(GLNode))))
        {
            return 0 ;
        }
        //字符長度爲1時,廣義表爲單個元素
        if(strlen(s) == 1)
        {
            (*ls)->tag = 0 ;
            (*ls)->data = *s ;
        }
        else
        {
            substr(s , s , 2 , strlen(s) - 2) ; //去掉最外層括號;
            p = (*ls) ;
            p->tag = 1 ;
            do
            {
                server(hsub , s) ; //獲取頭節點
                CreateGList(&(p->ptr.hp) , hsub) ;
                q = p ;
                if(*s != '\0')
                {
                    p = (GList)malloc(sizeof(GLNode)) ;
                    p->tag = 1 ;
                    q->ptr.tp = p ;
                }
                else
                {
                    p->ptr.tp = NULL ;
                }
            }while(*s != '\0') ;
        }
    }
    return 1 ;
}
/*
 *打印廣義表
 */
void printGList(GList ls)
{
    if(ls != NULL)
    {
        if(ls->tag == 0)
        {
            printf("%c " , ls->data) ;
        }
        else
        {
            printGList(ls->ptr.hp) ;
            printGList(ls->ptr.tp) ;
        }
    }
}
/*
 *以表頭和表尾建立廣義表
 */
int Merge(GList l1 , GList l2 , GList *ls)
{
    if(!((*ls) = (GList)malloc(sizeof(GLNode))))
    {
        return 0 ;
    }
    (*ls)->tag = 1 ;
    (*ls)->ptr.hp = l1 ;
    (*ls)->ptr.tp = l2 ;
    return 1 ;
}
/*
 *取得廣義表的長度
 */
int Depth(GList ls)
{
    GList p ;
    int max , depth ;
    if(ls == NULL)
    {
        return 1 ; //空表長度爲1
    }
    if(ls->tag == 0)
    {
        return 0 ; //單元素長度爲0
    }
    for(max = 0 , p = ls->ptr.tp; p ; p = p->ptr.tp)
    {
        depth = Depth(p) ;
        if(depth > max)
        {
            max = depth ;
        }
    }
    return max + 1 ;
}
/*
 *進行廣義表的複製
 */
int CopyGList(GList ls , GList *ls1)
{
    if(ls == NULL)
    {
        (*ls1) = NULL ;
    }
    else
    {
        if(!((*ls1)=(GList)malloc(sizeof(GLNode))))
        {
            return 0 ;
        }
        if(ls->tag == 0)
        {
            (*ls1)->tag = 0 ;
            (*ls1)->data = ls->data ;
        }
        else
        {
            (*ls1)->tag = 1 ;
            CopyGList(ls->ptr.hp , &((*ls1)->ptr.hp)) ;
            CopyGList(ls->ptr.tp , &((*ls1)->ptr.tp)) ;
        }
    }
}
/*
 *廣義表的取頭操作
 */
GList GetHead(GList ls)
{
    GList list = NULL ;
    if(ls->tag == 1)
    {
        list = ls->ptr.hp ;
    }
    return list ;
}
/*
 *廣義表的取尾操作
 */
GList GetTail(GList ls)
{
    GList list = NULL ;
    if(ls->tag == 1)
    {
        list = ls->ptr.tp ;
    }
    return list ;
}
//進行廣義表的測試
void main()
{
  GList ls1 , ls2 , ls3 , ls4 ;
  char s[MAXSIZE] , s1[MAXSIZE];
  scanf("%s" , s) ;
  CreateGList(&ls1 , s) ;
  scanf("%s" , s1) ;
  CreateGList(&ls2 , s1) ;
  printGList(ls1) ;
  printf("\n") ;
  printGList(ls2) ;
  printf("\n") ;
  printf("the depth of ls1 is %d \n" , Depth(ls1)) ;
  printf("the depth of ls2 is %d \n" , Depth(ls2)) ;
  Merge(ls1 , ls2 , &ls3) ;
  printGList(ls3) ;
  printf("\n") ;
  printf("the depth of ls3 is %d \n" , Depth(ls3)) ;
  CopyGList(ls3 , &ls4) ;
  printGList(ls4) ;
  printf("\n") ;
  printf("the depth of ls4 is %d \n" , Depth(ls4)) ;
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章