zoukankan      html  css  js  c++  java
  • 数据结构30:广义表的复制

    对于任意一个非空广义表来说,都是由两部分组成:表头和表尾。反之,只要确定的一个广义表的表头和表尾,那么这个广义表就可以唯一确定下来。

    复制一个广义表,也是不断的复制表头和表尾的过程。如果表头或者表尾同样是一个广义表,依旧复制其表头和表尾。

    所以,复制广义表的过程,其实就是不断的递归,复制广义表中表头和表尾的过程。

    递归的出口有两个:

    1. 如果当前遍历的数据元素为空表,则直接返回空表。
    2. 如果当前遍历的数据元素为该表的一个原子,那么直接复制,返回即可。


    还拿广义表C为例:


    图1 广义表C的结构示意图


    代码实现:

    #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; }
    void copyGlist(Glist C, Glist *T)
    {   
    // 如果C为空表,那么复制表直接为空表   if (!C)
      {     
    *T=NULL;   }   else
      {     *T = (Glist)malloc(sizeof(GNode));// C不是空表,给T申请内存空间     // 申请失败,程序停止     if (!*T)
        {       exit(
    0);     }     (*T)->tag = C->tag;  // 复制表C的tag值     // 判断当前表元素是否为原子,如果是,直接复制     if (C->tag == 0)
        {       (
    *T)->atom = C->atom;     }
        else  
        {
          // 运行到这,说明复制的是子表       copyGlist(C->ptr.hp, &((*T)->ptr.hp));  // 复制表头       copyGlist(C->ptr.tp, &((*T)->ptr.tp));  // 复制表尾     }   } }
    int main(int argc, const char *argv[])
    {   Glist C
    = NULL;   C = creatGlist(C);   Glist T = NULL;   copyGlist(C, &T);   printf("%c", T->ptr.hp->atom);   
      return 0; }
    运行结果: a

    总结

    在实现复制广义表的过程中,实现函数为:

    void copyGlist(Glist C, Glist *T);

    其中,Glist *T,等同于: struct GLNode* *T,此为二级指针,不是一级指针。在主函数中,调用此函数时,传入的是指针 T 的地址,而不是 T 。

    这里使用的是地址传递,而不是值传递。如果在这里使用值传递,会导致广义表 T 丢失结点,复制失败。

  • 相关阅读:
    (六)定时测量
    (五)内核同步
    (四)中断和异常
    smba
    (四)支持 Nand Flash
    (三) 支持Nor Flash
    Convolutional Neural Networks(5):Pooling Layer
    Convolutional Neural Networks(4):Feature map size,Padding and Stride
    Convolutional Neural Networks(3):Convolution and Channels
    Convolutional Neural Networks(2):Sparse Interactions, Receptive Field and Parameter Sharing
  • 原文地址:https://www.cnblogs.com/ciyeer/p/9040553.html
Copyright © 2011-2022 走看看