三木社区

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 339|回复: 0
打印 上一主题 下一主题

C语言数据结构-bo6-5.c

[复制链接]

1562

主题

1564

帖子

4904

积分

博士

Rank: 8Rank: 8

积分
4904
跳转到指定楼层
楼主
发表于 2017-9-1 09:11:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /* bo6-5.c 树的二叉链表(孩子-兄弟)存储(存储结构由c6-5.h定义)的基本操作(17个) */
  2. Status InitTree(CSTree *T)
  3. { /* 操作结果: 构造空树T */
  4.    *T=NULL;
  5.    return OK;
  6. }

  7. void DestroyTree(CSTree *T)
  8. { /* 初始条件: 树T存在。操作结果: 销毁树T */
  9.    if(*T)
  10.    {
  11.      if((*T)->firstchild) /* T有长子 */
  12.        DestroyTree(&(*T)->firstchild); /* 销毁T的长子为根结点的子树 */
  13.      if((*T)->nextsibling) /* T有下一个兄弟 */
  14.        DestroyTree(&(*T)->nextsibling); /* 销毁T的下一个兄弟为根结点的子树 */
  15.      free(*T); /* 释放根结点 */
  16.      *T=NULL;
  17.    }
  18. }

  19. typedef CSTree QElemType; /* 定义队列元素类型 */
  20. #include"c3-2.h" /* 定义LinkQueue类型 */
  21. #include"bo3-2.c" /* LinkQueue类型的基本操作 */
  22. Status CreateTree(CSTree *T)
  23. { /* 构造树T */
  24.    char c[20]; /* 临时存放孩子结点(设不超过20个)的值 */
  25.    CSTree p,p1;
  26.    LinkQueue q;
  27.    int i,l;
  28.    InitQueue(&q);
  29.    printf("请输入根结点(字符型,空格为空): ");
  30.    scanf("%c%*c",&c[0]);
  31.    if(c[0]!=Nil) /* 非空树 */
  32.    {
  33.      *T=(CSTree)malloc(sizeof(CSNode)); /* 建立根结点 */
  34.      (*T)->data=c[0];
  35.      (*T)->nextsibling=NULL;
  36.      EnQueue(&q,*T); /* 入队根结点的指针 */
  37.      while(!QueueEmpty(q)) /* 队不空 */
  38.      {
  39.        DeQueue(&q,&p); /* 出队一个结点的指针 */
  40.        printf("请按长幼顺序输入结点%c的所有孩子: ",p->data);
  41.        gets(c);
  42.        l=strlen(c);
  43.        if(l>0) /* 有孩子 */
  44.        {
  45.          p1=p->firstchild=(CSTree)malloc(sizeof(CSNode)); /* 建立长子结点 */
  46.          p1->data=c[0];
  47.          for(i=1;i<l;i++)
  48.          {
  49.            p1->nextsibling=(CSTree)malloc(sizeof(CSNode)); /* 建立下一个兄弟结点 */
  50.            EnQueue(&q,p1); /* 入队上一个结点 */
  51.            p1=p1->nextsibling;
  52.            p1->data=c[i];
  53.          }
  54.          p1->nextsibling=NULL;
  55.          EnQueue(&q,p1); /* 入队最后一个结点 */
  56.        }
  57.        else
  58.          p->firstchild=NULL;
  59.      }
  60.    }
  61.    else
  62.      *T=NULL;
  63.    return OK;
  64. }

  65. #define ClearTree DestroyTree /* 二者操作相同 */

  66. Status TreeEmpty(CSTree T)
  67. { /* 初始条件: 树T存在。操作结果: 若T为空树,则返回TURE,否则返回FALSE */
  68.    if(T) /* T不空 */
  69.      return FALSE;
  70.    else
  71.      return TRUE;
  72. }

  73. int TreeDepth(CSTree T)
  74. { /* 初始条件: 树T存在。操作结果: 返回T的深度 */
  75.    CSTree p;
  76.    int depth,max=0;
  77.    if(!T) /* 树空 */
  78.      return 0;
  79.    if(!T->firstchild) /* 树无长子 */
  80.      return 1;
  81.    for(p=T->firstchild;p;p=p->nextsibling)
  82.    {
  83.      depth=TreeDepth(p);
  84.      if(depth>max)
  85.        max=depth;
  86.    }
  87.    return max+1;
  88. }

  89. TElemType Value(CSTree p)
  90. { /* 返回p所指结点的值 */
  91.    return p->data;
  92. }

  93. TElemType Root(CSTree T)
  94. { /* 初始条件: 树T存在。操作结果: 返回T的根 */
  95.    if(T)
  96.      return Value(T);
  97.    else
  98.      return Nil;
  99. }

  100. CSTree Point(CSTree T,TElemType s)
  101. { /* 返回二叉链表(孩子-兄弟)树T中指向元素值为s的结点的指针。另加 */
  102.    LinkQueue q;
  103.    QElemType a;
  104.    if(T) /* 非空树 */
  105.    {
  106.      InitQueue(&q); /* 初始化队列 */
  107.      EnQueue(&q,T); /* 根结点入队 */
  108.      while(!QueueEmpty(q)) /* 队不空 */
  109.      {
  110.        DeQueue(&q,&a); /* 出队,队列元素赋给a */
  111.        if(a->data==s)
  112.          return a;
  113.        if(a->firstchild) /* 有长子 */
  114.          EnQueue(&q,a->firstchild); /* 入队长子 */
  115.        if(a->nextsibling) /* 有下一个兄弟 */
  116.          EnQueue(&q,a->nextsibling); /* 入队下一个兄弟 */
  117.      }
  118.    }
  119.    return NULL;
  120. }

  121. Status Assign(CSTree *T,TElemType cur_e,TElemType value)
  122. { /* 初始条件: 树T存在,cur_e是树T中结点的值。操作结果: 改cur_e为value */
  123.    CSTree p;
  124.    if(*T) /* 非空树 */
  125.    {
  126.      p=Point(*T,cur_e); /* p为cur_e的指针 */
  127.      if(p) /* 找到cur_e */
  128.      {
  129.        p->data=value; /* 赋新值 */
  130.        return OK;
  131.      }
  132.    }
  133.    return Nil; /* 树空或没找到 */
  134. }

  135. TElemType Parent(CSTree T,TElemType cur_e)
  136. { /* 初始条件: 树T存在,cur_e是T中某个结点 */
  137.    /* 操作结果: 若cur_e是T的非根结点,则返回它的双亲,否则函数值为"空" */
  138.    CSTree p,t;
  139.    LinkQueue q;
  140.    InitQueue(&q);
  141.    if(T) /* 树非空 */
  142.    {
  143.      if(Value(T)==cur_e) /* 根结点值为cur_e */
  144.        return Nil;
  145.      EnQueue(&q,T); /* 根结点入队 */
  146.      while(!QueueEmpty(q))
  147.      {
  148.        DeQueue(&q,&p);
  149.        if(p->firstchild) /* p有长子 */
  150.        {
  151.          if(p->firstchild->data==cur_e) /* 长子为cur_e */
  152.            return Value(p); /* 返回双亲 */
  153.          t=p; /* 双亲指针赋给t */
  154.          p=p->firstchild; /* p指向长子 */
  155.          EnQueue(&q,p); /* 入队长子 */
  156.          while(p->nextsibling) /* 有下一个兄弟 */
  157.          {
  158.            p=p->nextsibling; /* p指向下一个兄弟 */
  159.            if(Value(p)==cur_e) /* 下一个兄弟为cur_e */
  160.              return Value(t); /* 返回双亲 */
  161.            EnQueue(&q,p); /* 入队下一个兄弟 */
  162.          }
  163.        }
  164.      }
  165.    }
  166.    return Nil; /* 树空或没找到cur_e */
  167. }

  168. TElemType LeftChild(CSTree T,TElemType cur_e)
  169. { /* 初始条件: 树T存在,cur_e是T中某个结点 */
  170.    /* 操作结果: 若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回"空" */
  171.    CSTree f;
  172.    f=Point(T,cur_e); /* f指向结点cur_e */
  173.    if(f&&f->firstchild) /* 找到结点cur_e且结点cur_e有长子 */
  174.      return f->firstchild->data;
  175.    else
  176.      return Nil;
  177. }

  178. TElemType RightSibling(CSTree T,TElemType cur_e)
  179. { /* 初始条件: 树T存在,cur_e是T中某个结点 */
  180.    /* 操作结果: 若cur_e有右兄弟,则返回它的右兄弟,否则返回"空" */
  181.    CSTree f;
  182.    f=Point(T,cur_e); /* f指向结点cur_e */
  183.    if(f&&f->nextsibling) /* 找到结点cur_e且结点cur_e有右兄弟 */
  184.      return f->nextsibling->data;
  185.    else
  186.      return Nil; /* 树空 */
  187. }

  188. Status InsertChild(CSTree *T,CSTree p,int i,CSTree c)
  189. { /* 初始条件: 树T存在,p指向T中某个结点,1≤i≤p所指结点的度+1,非空树c与T不相交 */
  190.    /* 操作结果: 插入c为T中p结点的第i棵子树 */
  191.    /* 因为p所指结点的地址不会改变,故p不需是引用类型 */
  192.    int j;
  193.    if(*T) /* T不空 */
  194.    {
  195.      if(i==1) /* 插入c为p的长子 */
  196.      {
  197.        c->nextsibling=p->firstchild; /* p的原长子现是c的下一个兄弟(c本无兄弟) */
  198.        p->firstchild=c;
  199.      }
  200.      else /* 找插入点 */
  201.      {
  202.        p=p->firstchild; /* 指向p的长子 */
  203.        j=2;
  204.        while(p&&j<i)
  205.        {
  206.          p=p->nextsibling;
  207.          j++;
  208.        }
  209.        if(j==i) /* 找到插入位置 */
  210.        {
  211.          c->nextsibling=p->nextsibling;
  212.          p->nextsibling=c;
  213.        }
  214.        else /* p原有孩子数小于i-1 */
  215.          return ERROR;
  216.      }
  217.      return OK;
  218.    }
  219.    else /* T空 */
  220.      return ERROR;
  221. }

  222. Status DeleteChild(CSTree *T,CSTree p,int i)
  223. { /* 初始条件: 树T存在,p指向T中某个结点,1≤i≤p所指结点的度 */
  224.    /* 操作结果: 删除T中p所指结点的第i棵子树 */
  225.    /* 因为p所指结点的地址不会改变,故p不需是引用类型 */
  226.    CSTree b;
  227.    int j;
  228.    if(*T) /* T不空 */
  229.    {
  230.      if(i==1) /* 删除长子 */
  231.      {
  232.        b=p->firstchild;
  233.        p->firstchild=b->nextsibling; /* p的原次子现是长子 */
  234.        b->nextsibling=NULL;
  235.        DestroyTree(&b);
  236.      }
  237.      else /* 删除非长子 */
  238.      {
  239.        p=p->firstchild; /* p指向长子 */
  240.        j=2;
  241.        while(p&&j<i)
  242.        {
  243.          p=p->nextsibling;
  244.          j++;
  245.        }
  246.        if(j==i) /* 找到第i棵子树 */
  247.        {
  248.          b=p->nextsibling;
  249.          p->nextsibling=b->nextsibling;
  250.          b->nextsibling=NULL;
  251.          DestroyTree(&b);
  252.        }
  253.        else /* p原有孩子数小于i */
  254.          return ERROR;
  255.      }
  256.      return OK;
  257.    }
  258.    else
  259.      return ERROR;
  260. }

  261. void PreOrderTraverse(CSTree T,void(*Visit)(TElemType))
  262. { /* 先根遍历孩子-兄弟二叉链表结构的树T */
  263.    if(T)
  264.    {
  265.      Visit(Value(T)); /* 先访问根结点 */
  266.      PreOrderTraverse(T->firstchild,Visit); /* 再先根遍历长子子树 */
  267.      PreOrderTraverse(T->nextsibling,Visit); /* 最后先根遍历下一个兄弟子树 */
  268.    }
  269. }

  270. void PostOrderTraverse(CSTree T,void(*Visit)(TElemType))
  271. { /* 后根遍历孩子-兄弟二叉链表结构的树T */
  272.    CSTree p;
  273.    if(T)
  274.    {
  275.      if(T->firstchild) /* 有长子 */
  276.      {
  277.        PostOrderTraverse(T->firstchild,Visit); /* 后根遍历长子子树 */
  278.        p=T->firstchild->nextsibling; /* p指向长子的下一个兄弟 */
  279.        while(p)
  280.        {
  281.          PostOrderTraverse(p,Visit); /* 后根遍历下一个兄弟子树 */
  282.          p=p->nextsibling; /* p指向再下一个兄弟 */
  283.        }
  284.      }
  285.      Visit(Value(T)); /* 最后访问根结点 */
  286.    }
  287. }

  288. void LevelOrderTraverse(CSTree T,void(*Visit)(TElemType))
  289. { /* 层序遍历孩子-兄弟二叉链表结构的树T */
  290.    CSTree p;
  291.    LinkQueue q;
  292.    InitQueue(&q);
  293.    if(T)
  294.    {
  295.      Visit(Value(T)); /* 先访问根结点 */
  296.      EnQueue(&q,T); /* 入队根结点的指针 */
  297.      while(!QueueEmpty(q)) /* 队不空 */
  298.      {
  299.        DeQueue(&q,&p); /* 出队一个结点的指针 */
  300.        if(p->firstchild) /* 有长子 */
  301.        {
  302.          p=p->firstchild;
  303.          Visit(Value(p)); /* 访问长子结点 */
  304.          EnQueue(&q,p); /* 入队长子结点的指针 */
  305.          while(p->nextsibling) /* 有下一个兄弟 */
  306.          {
  307.            p=p->nextsibling;
  308.            Visit(Value(p)); /* 访问下一个兄弟 */
  309.            EnQueue(&q,p); /* 入队兄弟结点的指针 */
  310.          }
  311.        }
  312.      }
  313.    }
  314. }
复制代码


回复

使用道具 举报

Archiver|手机版|小黑屋|三木电子社区 ( 辽ICP备11000133号-4 )

辽公网安备 21021702000620号

GMT+8, 2025-5-12 01:03 , Processed in 0.061772 second(s), 23 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表