一、內存申請
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 > 0)\ {\ 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 == 0 && pstack->ptags == 0) { LH_MALLOC(pstack->ptrees,TreeNode,sizeof(TreeNode)*5); LH_MALLOC(pstack->ptags,int,sizeof(int)*5); pstack->maxsize=5; } if(pstack->index < pstack->maxsize) { pstack->ptrees[pstack->index++]=node; } else { TreeNode* tmpTrees; int* tmptags; LH_MEMORY_MOV(tmpTrees, sizeof(TreeNode)*pstack->maxsize*2, pstack->ptrees, sizeof(TreeNode)*pstack->maxsize, TreeNode); LH_MEMORY_MOV(tmptags, sizeof(int)*pstack->maxsize*2, pstack->ptags, sizeof(int)*pstack->maxsize, int); pstack->ptrees=tmpTrees; pstack->ptags=tmptags; pstack->maxsize=pstack->maxsize*2; pstack->ptrees[pstack->index++]=node; } } /*彈出棧*/ TreeNode pop(LinearStack* pstack) { if(pstack->index > 0) { return pstack->ptrees[--pstack->index]; } } void main() { LinearStack* pstack=getALinearStack(); if(NULL == pstack) retrun; for(int i=0;i<60000;i++) { a.v=i; push(pstack,a); } for(int j=0;j<60000;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 > 0) { 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 > 0) { 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 > 0) { while(NULL != pnode) { push(pstack,*pnode); pstack->ptags[pstack->index-1]=0; pnode=pnode->pleft; } if(pstack->ptags[pstack->index-1]==0) { pstack->ptags[pstack->index-1]=1; pnode=pstack->ptrees[pstack->index-1].pright; } else { while(pstack->ptags[pstack->index-1]==1) { 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=0;c.pright=0; d.v='d';d.pleft=0;d.pright=&f; e.v='e';e.pleft=&g;e.pright=0; f.v='f';f.pleft=0;f.pright=0; g.v='g';g.pleft=0;g.pright=0; } 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=0;c.pright=0; d.v='d';d.pleft=0;d.pright=&f; e.v='e';e.pleft=&g;e.pright=0; f.v='f';f.pleft=0;f.pright=0; g.v='g';g.pleft=0;g.pright=0; } 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); }