一、内存申请

1.建议使用calloc申请内存,尽量不要使用malloc。

 calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

2.申请内存大小必须大于0.

   (1)使用0字节长度申请内存的行为是没有定义的,在引用内存申请函数返回地址时会引发不可预知错误,对于可能出现申请0长度内存的情况非常有必要判断,避免出现这种情况。

(2)使用负数长度申请内存,负数会被当成一个很大的无符号整数,导致申请内存过大而出现失败。

3.申请内存后检查是否申请成功,即检查返回指针是否为NULL,即是否为0。

二、内存释放

1.申请的内存一定需要释放,有且仅能释放一次

2.禁止释放或函数内返回非动态申请的内存(栈中的内存,函数中的临时变量等)

   3.指针释放后必须将指针指向空指针,否则会出现野指针的情况。

三、附加一个C实现的存储二叉树元素的动态栈

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define LH_MALLOC(pMemory,Type,Size) \
if(Size > )\
{\
pMemory=(Type*)calloc(Size/sizeof(Type),sizeof(Type));\
}\
else\
{\
pMemory=NULL;\
}\ #define LH_FREE(p) if(NULL != p){free(p);p=NULL;} #define LH_MEMORY_MOV(dst,dstSize,src,srcSize,Type)\
LH_MALLOC(dst,Type,dstSize)\
memcpy(dst,src,srcSize);\
   LH_FREE(src)\ typedef struct tagTreeNode
{
int v;
struct tagTreeNode* pleft;
struct tagTreeNode* pright;
}TreeNode;

typedef struct tagLinearStack
{
   TreeNode* ptrees;
   int* ptags;
   int maxsize;
   int index;
}LinearStack;

/*获取一个栈指针*/
LinearStack* getALinearStack()
{
LinearStack* pstack;
LH_MALLOC(pstack,LinearStack,sizeof(LinearStack));
return pstack;
} /*释放栈,与getALinearStack成对使用*/
void freeLinearStack(LinearStack* pstack)
{
LH_FREE(pstack->ptags);
LH_FREE(pstack->ptrees);
LH_FREE(pstack);
} /*入栈*/
void push(LinearStack* pstack,TreeNode node)
{
if(pstack->ptrees == && pstack->ptags == )
{
LH_MALLOC(pstack->ptrees,TreeNode,sizeof(TreeNode)*);
LH_MALLOC(pstack->ptags,int,sizeof(int)*);
pstack->maxsize=;
} if(pstack->index < pstack->maxsize)
{
pstack->ptrees[pstack->index++]=node;
}
else
{
TreeNode* tmpTrees;
int* tmptags;
LH_MEMORY_MOV(tmpTrees,
   sizeof(TreeNode)*pstack->maxsize*,
    pstack->ptrees,
sizeof(TreeNode)*pstack->maxsize,
TreeNode); LH_MEMORY_MOV(tmptags,
   sizeof(int)*pstack->maxsize*,
     pstack->ptags,
     sizeof(int)*pstack->maxsize,
     int);
pstack->ptrees=tmpTrees;
pstack->ptags=tmptags;
pstack->maxsize=pstack->maxsize*;
pstack->ptrees[pstack->index++]=node;
}
} /*弹出栈*/
TreeNode pop(LinearStack* pstack)
{
if(pstack->index > )
{
return pstack->ptrees[--pstack->index];
}
} void main()
{
LinearStack* pstack=getALinearStack();
if(NULL == pstack)
retrun;
for(int i=;i<;i++)
{
a.v=i;
push(pstack,a);
}
for(int j=;j<;j++)
{
TreeNode node=pop(pstack);
printf("%d: %d \n",j,node.v);
}
freeLinearStack(pstack);
}

四、二叉树非递归遍历方法

void preOrder(TreeNode* pnode)
{
LinearStack* pstack=getALinearStack();
while(NULL != pnode || pstack->index > )
{
while(NULL!=pnode)
{
printf("%c ",pnode->v);
push(pstack,*pnode);
pnode=pnode->pleft;
}
pnode=pop(pstack);
pnode=pnode->pright;
}
freeLinearStack(pstack);
} void middleOrder(TreeNode* pnode)
{
LinearStack* pstack=getALinearStack();
while(NULL != pnode || pstack->index > )
{
while(NULL!=pnode)
{
push(pstack,*pnode);
pnode=pnode->pleft;
}
pnode=pop(pstack);
printf("%c ",pnode->v);
pnode=pnode->pright;
}
freeLinearStack(pstack);
} void postOrder(TreeNode* pnode)
{
LinearStack* pstack=getALinearStack();
while(NULL != pnode || pstack->index > )
{
while(NULL != pnode)
{
push(pstack,*pnode);
pstack->ptags[pstack->index-]=;
pnode=pnode->pleft;
}
if(pstack->ptags[pstack->index-]==)
{
pstack->ptags[pstack->index-]=;
pnode=pstack->ptrees[pstack->index-].pright;
}
else
{
while(pstack->ptags[pstack->index-]==)
{
pnode=pop(pstack);
printf("%c ",pnode->v);
}
pnode=NULL;
}
}
freeLinearStack(pstack);
} void init()
{
a.v='a';a.pleft=&b;a.pright=&c;
b.v='b';b.pleft=&d;b.pright=&e;
c.v='c';c.pleft=;c.pright=;
d.v='d';d.pleft=;d.pright=&f;
e.v='e';e.pleft=&g;e.pright=;
f.v='f';f.pleft=;f.pright=;
g.v='g';g.pleft=;g.pright=;
} void main()
{
init();
postOrder(&a);
}

五、线索二叉树

typedef enum{Link,Thread} PointerTag;

typedef struct tagTreeNode
{
char v;
PointerTag ltag,rtag;
struct tagTreeNode* pleft;
struct tagTreeNode* pright;
}TreeNode;
TreeNode a,b,c,d,e,f,g;
void init()
{
a.v='a';a.pleft=&b;a.pright=&c;
b.v='b';b.pleft=&d;b.pright=&e;
c.v='c';c.pleft=;c.pright=;
d.v='d';d.pleft=;d.pright=&f;
e.v='e';e.pleft=&g;e.pright=;
f.v='f';f.pleft=;f.pright=;
g.v='g';g.pleft=;g.pright=;
}
TreeNode *pre;
void InitThreadRootTree(TreeNode* ptree)
{
if(NULL != ptree)
{
InitThreadRootTree(ptree->pleft); if(ptree->pleft == NULL)
{
ptree->ltag=Thread;
ptree->pleft=pre;
}
if(pre->pright == NULL)
{
pre->rtag=Thread;
pre->pright=ptree;
}
pre=ptree; InitThreadRootTree(ptree->pright);
}
}
void BuildThread(TreeNode* phead,TreeNode* ptreeRoot)
{
if(NULL == ptreeRoot)
{
phead->ltag=Link;
phead->pleft=phead;
}
else
{ phead->ltag=Link;
phead->pleft=ptreeRoot;
pre=phead; InitThreadRootTree(ptreeRoot); pre->pright=phead;
pre->rtag=Thread;
phead->pright=pre;
}
} void midOrderThread(TreeNode* phead)
{
TreeNode* treeNode = phead->pleft;
while(phead != treeNode)
{
while(treeNode->ltag == Link)
{
treeNode=treeNode->pleft;
}
printf("%c ",treeNode->v);
while(treeNode->rtag==Thread && treeNode->pright != phead)
{
treeNode=treeNode->pright;
printf("%c ",treeNode->v);
}
treeNode=treeNode->pright;
}
} void main()
{
init();
TreeNode head;
head.rtag=Link;
head.pright=&head;
BuildThread(&head,&a);
midOrderThread(&head);
}

最新文章

  1. html 杂记
  2. 从一个Fragment跳转到另一个Fragment
  3. Linux&amp;shell 之Shell命令进阶
  4. web前端面试试题总结---其他
  5. spring mvc和web-flow的整合方案
  6. sqlite数据库如何远程连接?
  7. SQL运维
  8. Java爬网页数据,并存储到本地数据库中
  9. git从其他分支提取文件merge到当前分支
  10. Knockout.Js官网学习(Mapping高级用法二)
  11. from collections import namedtuple 使用
  12. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas
  13. C# switch-case中的或(or)操作
  14. 解决windows 下mysql 表名自动转成小写的问题
  15. Bezier曲线
  16. web三大组件的加载顺序
  17. CSS顶级技巧大放送,div+css布局必知
  18. Mysql数据库的增删改查
  19. WPF判断当前窗体是否为模态
  20. java容器 Map Set List

热门文章

  1. dropdownlist的OnSelectedIndexChanged方法不触发
  2. day103 跨域请求 与频率访问限制.
  3. centos7系统的进程管理
  4. day 53 Django form 组件 autu 组件
  5. innodb 源码分析 --锁
  6. 【11】JMicro微服务-配置管理
  7. 【mNOIP模拟赛Day 1】 T2 数颜色
  8. express中间件原理 &amp;&amp; 实现
  9. nodejs(三) --- nodejs进程与子进程
  10. hanlp的基本使用--python(自然语言处理)