树、内存、栈



#include <stdio.h>
#include <string.h>
#define MEMORY_SIZE 102400

typedef unsigned char BYte;
typedef void* PTr;
typedef PTr (*NOdefunc)(void);     //函数指针NOdefunc
typedef void (*DOfunc)(int n, PTr p);   //函数指针DOfunc

typedef struct _MEmory* PCmemory;
typedef struct _MEmory
{
 BYte amem[MEMORY_SIZE];     //存储数据
 int nmem_point;       //存数的字节数
} CMemory;

typedef struct _STack* PCstack;
typedef struct _STack
{
 PTr pcontent;        //树的当前结点
 PCstack pnext;        //指向上一个栈
} CStack;

typedef struct _Tree* PCtree;
typedef struct _Tree
{
 PTr pcontent;        //结点的内容
 PCtree pson;       //指向孩子结点的指针
 PCtree pbrother;       //指向兄弟结点的指针
} CTree;

void Minit(PCmemory pmem);
PTr Malloc(PCmemory pmem, int size);
PCstack Snew(void);
PCstack Spush(PCstack pstk, PTr p);
PCstack Spop(PCstack pstk, PTr* p);
PCtree Tnew(void);
void Taddson(PCtree ptree, NOdefunc f);
void Taddbrother(PCtree ptree, NOdefunc f);
void Tbrowse(PCtree ptree,DOfunc f, int n);
void Tbrowse_Satck(PCtree ptree, DOfunc f, int n);
PTr Node(void);
void Out(int n,PTr p);

static CMemory mem;       //静态区分配的内存,用于存储数据及字节数
PCmemory xpmem = &mem;       //指向该内存的指针

static char* aanode[28]=
 { "1","2","3",NULL,"4",NULL,"5", NULL,NULL,
   "6",NULL,"7","8",NULL, "9","10",NULL,"11",NULL,"12",NULL,NULL,
   NULL,NULL,NULL,NULL,NULL,NULL};
static int nnode=0;       //aanode[nnode]

int main(int argc, char* argv[])
{
 //printf("sizeof(aanode)/sizeof(aanode[0]) = %d\n", sizeof(aanode)/sizeof(aanode[0]));
 //printf("aanode[sizeof(aanode)/sizeof(aanode[0])] = %p\n", aanode[sizeof(aanode)/sizeof(aanode[0])]);
  
 Minit(xpmem);        //初始化分配的静态区内存
 PCtree ptree = Tnew();      //建立一个带虚根结点的空树
 Taddson(ptree, Node);      //为该树添加结点并赋予数据
 Tbrowse(ptree->pson, Out, 0);    //遍历该树
 Tbrowse_Satck(ptree->pson, Out, 0);   //遍历栈空间
}

/******************************************************************************/
void Minit(PCmemory pmem)     //内存空间初始化函数
{
 pmem->nmem_point = 0;      //初始字节数为0
}

/******************************************************************************/
PTr Malloc(PCmemory pmem, int size)   //在已申请的内存空间里分配空间
{
 int n_cur_mem_p;
 n_cur_mem_p = pmem->nmem_point;
 pmem->nmem_point += size;
 //return (PTr)(&(pmem->amem[n_cur_mem_p]));
 //进行内存边界检查
 return (pmem->nmem_point > n_cur_mem_p)&& (pmem->nmem_point < MEMORY_SIZE)?
   (PTr)(pmem->amem+n_cur_mem_p):NULL;
}

/******************************************************************************/
PCstack Snew(void)        //建立空栈
{
 return NULL;
}

/******************************************************************************/
PCstack Spush(PCstack pstk, PTr p)   //压栈操作,也在申请的内存空间分配
{
 PCstack pstknew;
 pstknew = (PCstack)Malloc(xpmem, sizeof(CStack));  //新申请一个栈单元空间
 pstknew->pcontent = p;      //将树的当前结点的数据压栈
 pstknew->pnext = pstk;      //
 return pstknew;       //重新定位栈的头指针,并返回(前插型)
}

/******************************************************************************/
PCstack Spop(PCstack pstk, PTr* pp)   //出栈操作
{
 if(pstk!=NULL)
 {
  *pp = pstk->pcontent;     //将当前栈单元的数据赋给树结点指针
  pstk = pstk->pnext;     //
  return pstk;       //重新定位栈的头指针,并返回
 }
 else
  return NULL;
}

/******************************************************************************/
PCtree Tnew(void)       //建立带虚根节点的空树
{
 PCtree proot;
 proot = (PCtree)Malloc(xpmem, sizeof(CTree));
 proot->pcontent = "ROOT";
 proot->pson=NULL;      //无孩子
 proot->pbrother=NULL;     //无兄弟
 return proot;        //返回该虚根节点的指针
}

/******************************************************************************/
void Taddson(PCtree ptree, NOdefunc f)  //添加孩子结点函数
{
 PTr p = f();
 if(p==NULL)
 {
  Taddbrother(ptree,f);    //若当前结点无孩子,则添加兄弟结点
 }
 else
 {
  PCtree ptreenew = (PCtree)Malloc(xpmem,sizeof(CTree));
  ptreenew->pson=NULL;
  ptreenew->pbrother=NULL;
  ptreenew->pcontent = p;
  ptree->pson = ptreenew;    //当前结点添加好了孩子结点
  Taddson(ptreenew,f);    //为该孩子结点添加孩子结点
           //(实现的操作:有孩子结点添加,无孩子则添加兄弟结点)
  Taddbrother(ptree,f);    //为当前结点添加兄弟结点
 }
}

/******************************************************************************/
void Taddbrother(PCtree ptree, NOdefunc f) //添加兄弟结点函数
{
 PTr p = f();
 if(p==NULL)
  return;        //若也无兄弟结点,则结束
 else
 {
  PCtree ptreenew = (PCtree)Malloc(xpmem,sizeof(CTree));
  ptreenew->pson=NULL;
  ptreenew->pbrother=NULL;
  ptreenew->pcontent = p;
  ptree->pbrother = ptreenew;   //当前结点添加好了兄弟结点
  Taddson(ptreenew,f);    //为该兄弟结点添加孩子结点
 }
}

/******************************************************************************/
void Tbrowse(PCtree ptree,DOfunc f, int n) //遍历树
{
 if(ptree!=NULL)
 {
  f(n,ptree->pcontent);    //先结点
  Tbrowse(ptree->pson,f,n+1);   //接着孩子结点
  Tbrowse(ptree->pbrother,f,n);  //最后兄弟结点
 }
}

/******************************************************************************/
void Tbrowse_Satck(PCtree ptree, DOfunc f, int n)//遍历栈空间,n=0
{
 PCstack pstk;
 pstk = Snew();        //新建一个空栈
 while(1)
 {
  f(n, ptree->pcontent);     //打印当前栈单元的内容
  //这个分支里,栈的首指针没有移动
  if(ptree->pson==NULL)     //当前结点无孩子结点,则转向其兄弟结点
  {
   while(ptree->pbrother==NULL)  //若无兄弟结点
   {
    pstk = Spop(pstk,(PTr*)&ptree); //出栈
    n--;       //深度-1
    if(pstk == NULL)
     return;      //出口:栈为空
   } 
   ptree = ptree->pbrother;   //取当前结点的兄弟结点
  }
  //这个分支里,栈的首指针有移动
  else   
  {
   pstk = Spush(pstk,ptree);   //压栈
   n++;        //深度+1
   ptree = ptree->pson;    //取当前结点的孩子结点
  } 
 }
}
/*
总结:栈的首指针在求取孩子结点过程中有变化(pstk = Spush(pstk,ptree);),而在求取兄弟结点过程中无改变.
 所以,求取孩子结点1,2,到这里栈的内容指针指向的是结点2;此后求取3,4,5,栈的内容指针都没有发生改变;
 到结点5时,其没有兄弟结点,则对ptree重新定位为结点2(pstk = Spop(pstk,(PTr*)&ptree);),
 而栈的内容指针也重新定位为结点1;
 接着再继续...直到栈为空为止。
*/

/******************************************************************************/
PTr Node(void)
{
 return aanode[nnode++];
}

/******************************************************************************/
void Out(int n,PTr p)
{
 int i;
 for(i=0; i<n; i++)
 {
  printf("_");
 }
 printf("%s\n",p);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值