树,好像生活中大家随处可见,今天写的是关于我们数据结构中的二叉树,所谓的二叉树--》结点的一个有限集合,该集合或者为空,或者是由一个根节点+左子树+右子树组成;
下面是对二叉树一些接口的实现,主要包括以下几部分:
1. 二叉树创建 --》2. 二叉树拷贝 --》3. 前序遍历---递归 --》4. 前序遍历---非递归 --》5. 中序遍历---递归 --》6. 中序遍历---非递归 --》7. 后续遍历---递归 --》8. 后续遍历---非递归 --》9. 层序遍历 --》10. 二叉树的销毁 --》11. 二叉树的镜像---非递归 --》12. 二叉树的镜像---递归 --》13. 求二叉树中结点的个数 --》14. 求二叉树中叶子结点的个数 --15. 求二叉树中第K层结点的个数 --》16. 求二叉树的高度 --》17. 在二叉树中查找值为data的结点,找到返回该结点,否则返回空 --》18. 检测一个节点是否在二叉树中 --》19. 检测一棵树是否为完全二叉树
下面是对这些接口实现的代码:
#define _CRT_SECURE_NO_WARNINGS 0; #include <assert.h> #include <stdlib.h> #include "bin_tree.h" #include <stdio.h> #include "stack.h" #include "queue .h" //创建结点 pBTNode BuyNode(BTDataType data) { pBTNode pNewNode = (pBTNode)malloc(sizeof(BTNode)); if (NULL == pNewNode) assert(pNewNode); pNewNode->_data = data; pNewNode->_pLeft = NULL; pNewNode->_pRight = NULL; return pNewNode; } // 二叉树创建 --->前序遍历 void creatTree(pBTNode* pRoot, BTDataType arr[], int size, BTDataType invoild) { assert(pRoot); int index = 0; _creatTree(pRoot, arr, size, &index, invoild); } void _creatTree(pBTNode* pRoot, BTDataType arr[], int size, int *index, BTDataType invoild) { assert(pRoot); assert(index); if (*index < size && arr[*index] != invoild) { *pRoot = BuyNode(arr[*index]); ++(*index); _creatTree(&(*pRoot)->_pLeft, arr, size, index, invoild); ++(*index); _creatTree(&(*pRoot)->_pRight, arr, size, index, invoild); } } // 二叉树拷贝 --前序遍历 pBTNode CopyBinTree(pBTNode pRoot) { pBTNode pCur=NULL; if (pRoot) { pCur = BuyNode(pRoot->_data); if (pRoot->_pLeft) pCur->_pLeft=CopyBinTree(pRoot->_pLeft); if (pRoot->_pRight) pCur->_pRight=CopyBinTree(pRoot->_pRight); } return pCur; } // 前序遍历---递归 void PreOrder(pBTNode pRoot) { if (pRoot) { printf("%c ", pRoot->_data); PreOrder(pRoot->_pLeft); PreOrder(pRoot->_pRight); } } // 前序遍历---非递归 void PreOrderNor(pBTNode pRoot) { Stack s; pBTNode pCur = NULL; if (NULL == pRoot) return; StackInit(&s); pCur = pRoot; while (pCur) { printf("%c ", pCur->_data); if (pCur->_pRight) StackPush(&s, pCur->_pRight); if (pCur->_pLeft) { pCur = pCur->_pLeft; continue; } if (IsEmptyStack(&s)) return; pCur = StackTop(&s); StackPop(&s); } } // 中序遍历---递归 void InOrder(pBTNode pRoot) { if (pRoot) { if (pRoot->_pLeft) InOrder(pRoot->_pLeft); printf("%c ", pRoot->_data); if (pRoot->_pRight) InOrder(pRoot->_pRight); } } //中序遍历---非递归 void InOrderNor(pBTNode pRoot) { pBTNode pCur = NULL; Stack s; StackInit(&s); if (NULL == pRoot) return; pCur = pRoot; while (pCur || !IsEmptyStack(&s)) { if (pCur != NULL) { StackPush(&s, pCur); pCur = pCur->_pLeft; } else { pCur = StackTop(&s); StackPop(&s); printf("%c ", pCur->_data); pCur = pCur->_pRight; } } } // 后序遍历---递归 void PostOrder(pBTNode pRoot) { if (pRoot) { if (pRoot->_pLeft) PostOrder(pRoot->_pLeft); if (pRoot->_pRight) PostOrder(pRoot->_pRight); printf("%c ", pRoot->_data); } } // 后序遍历---非递归 void PostOrderNor(pBTNode pRoot) { pBTNode pCur = NULL; pBTNode pTop = NULL; pBTNode pPrev = NULL; Stack s; StackInit(&s); if (NULL == pRoot) return; pCur = pRoot; while (pCur || !IsEmptyStack(&s)) { while(pCur != NULL) { StackPush(&s, pCur); pCur = pCur->_pLeft; } pTop = StackTop(&s); if (pTop->_pRight!=NULL && pTop->_pRight!=pPrev) { pCur = pTop->_pRight; } else { printf("%c ", pTop->_data); pPrev = pTop; StackPop(&s); } } } //层序遍历--循环 void LevelOrderNor(pBTNode pRoot) { Queue q; QueueInit(&q); if (pRoot) { QueuePush(&q, pRoot); while (!QueueEmpty(&q)) { pRoot = q._pHead->_data; QueuePop(&q); printf("%c ", pRoot->_data); if (pRoot->_pLeft) QueuePush(&q, pRoot->_pLeft); if (pRoot->_pRight) QueuePush(&q, pRoot->_pRight); } } } // 二叉树的销毁 void DetroyBinTree(pBTNode* pRoot) { assert(pRoot); if (*pRoot) { if ((*pRoot)->_pLeft) DetroyBinTree(&(*pRoot)->_pLeft); if ((*pRoot)->_pRight) DetroyBinTree(&(*pRoot)->_pRight); free(*pRoot); *pRoot = NULL; } } // 二叉树的镜像---非递归 void MirrorBinTreeNor(pBTNode* pRoot) { assert(pRoot); Queue q; QueueInit(&q); if (*pRoot) { pBTNode pCur = *pRoot; QueuePush(&q, pCur); while (!QueueEmpty(&q)) { pCur = q._pHead->_data; QueuePop(&q); if (pCur->_pLeft) QueuePush(&q, pCur->_pLeft); if (pCur->_pRight) QueuePush(&q, pCur->_pRight); if (pCur->_pLeft || pCur->_pRight) { BTNode* temp = pCur->_pLeft; pCur->_pLeft = pCur->_pRight; pCur->_pRight = temp; } } } } // 二叉树的镜像---递归 void MirrorBinTree(pBTNode* pRoot) { assert(pRoot); if (*pRoot) { pBTNode pCur = *pRoot; pBTNode pTemp = NULL; if (NULL==pCur->_pLeft || NULL==pCur->_pRight) return; pTemp = pCur->_pLeft; pCur->_pLeft = pCur->_pRight; pCur->_pRight = pTemp; if (pCur->_pLeft) MirrorBinTree(&pCur->_pLeft); if (pCur->_pRight) MirrorBinTree(&pCur->_pRight); } } // 求二叉树中结点的个数 int BinTreeSize(pBTNode pRoot) { if (NULL == pRoot) return 0; return 1 + BinTreeSize(pRoot->_pLeft) + BinTreeSize(pRoot->_pRight); } // 求二叉树中叶子结点的个数 int BinTreeLeaf(pBTNode pRoot) { if (NULL == pRoot) return 0; if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight) return 1; return BinTreeLeaf(pRoot->_pLeft) + BinTreeLeaf(pRoot->_pRight);; } // 求二叉树的高度 int BinTreeHeight(pBTNode pRoot) { int treeHeight = 0; if (pRoot) { int leftHeight = BinTreeHeight(pRoot->_pLeft); int rightHeight = BinTreeHeight(pRoot->_pRight); treeHeight = leftHeight > rightHeight ? leftHeight+1 : rightHeight+1; } return treeHeight; } // 求二叉树中第K层结点的个数 int BinTreeKLevelNode(pBTNode pRoot, int K) { if (NULL == pRoot || (K<=0 || K>BinTreeHeight(pRoot))) return 0; if (1 == K) return 1; return BinTreeKLevelNode(pRoot->_pLeft, K - 1) + BinTreeKLevelNode(pRoot->_pRight, K - 1); } // 在二叉树中查找值为data的结点,找到返回该结点,否则返回空 pBTNode Find(pBTNode pRoot, BTDataType data) { pBTNode pCur = NULL; if (pRoot) { if (pRoot->_data == data) return pRoot; else { if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight) return NULL; else { if ((pCur = Find(pRoot->_pLeft, data)) != NULL || (pCur = Find(pRoot->_pRight, data)) != NULL) return pCur; } } } return NULL; } // 检测一个节点是否在二叉树中 int IsNodeInBinTree(pBTNode pRoot, pBTNode pNode) { int ret = 0; if (pRoot) { if (pRoot == pNode) return 1; else { if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight) return 0; if ((ret = IsNodeInBinTree(pRoot->_pLeft, pNode)) || (ret = IsNodeInBinTree(pRoot->_pRight, pNode))) return ret; } } return 0; } // 检测一棵树是否为完全二叉树 int IsCompleteBinTree(pBTNode pRoot) { Queue q; pBTNode pCur; QueueInit(&q); if (NULL == pRoot) //空树 return 1; if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight) //只有一个结点 return 1; QueuePush(&q, pRoot); while (q._pHead->_data!=NULL) //多个结点进行处置 { pCur = q._pHead->_data; QueuePop(&q); QueuePush(&q,pCur->_pLeft); QueuePush(&q,pCur->_pRight); } while (!QueueEmpty(&q)) { if (q._pHead->_data != NULL) return 0; QueuePop(&q); } return 1; }
下面是这些接口的测试代码:
#define _CRT_SECURE_NO_WARNINGS 0; #include <stdio.h> #include "bin_tree.h" //测试拷贝二叉树 void testCopyBinTree(pBTNode pRoot) { pBTNode pCur = NULL; pCur = CopyBinTree(pRoot); } //测试二叉树 void testBinTree() { pBTNode pRoot = NULL; int ret; pBTNode pCur = NULL; BTDataType str[] = { 'A', 'B', 'D', '#', '#', '#', 'C', 'E', '#', '#', 'F' }; int size = sizeof(str); creatTree(&pRoot, str, size, '#'); testCopyBinTree(pRoot); printf("前序遍历--递归---》"); PreOrder(pRoot); printf("\n"); printf("前序遍历--循环---》"); PreOrderNor(pRoot); printf("\n"); printf("中序遍历--递归---》"); InOrder(pRoot); printf("\n"); printf("中序遍历--循环---》"); InOrderNor(pRoot); printf("\n"); printf("后序遍历--递归---》"); PostOrder(pRoot); printf("\n"); printf("后序遍历--循环---》"); PostOrderNor(pRoot); printf("\n"); printf("层序遍历--循环---》"); LevelOrderNor(pRoot); //DetroyBinTree(&pRoot); printf("\n"); printf("前序遍历--循环---镜像后》"); MirrorBinTreeNor(&pRoot); printf("\n"); printf("前序遍历--递归---镜像后》"); PreOrderNor(pRoot); MirrorBinTree(&pRoot); ret=BinTreeSize(pRoot); ret=BinTreeLeaf(pRoot); ret=BinTreeHeight(pRoot); ret = BinTreeKLevelNode(pRoot, 6); pCur= Find(pRoot, 'E'); ret=IsNodeInBinTree(pRoot, pCur); ///////创建完全二叉树/////// pBTNode pRoot = NULL; int ret; BTDataType str[] = { 'A', 'B', 'D', '#', '#', 'E', '#', '#', 'C', 'F'}; BTDataType str[] = { ' ' }; int size = sizeof(str); creatTree(&pRoot, str, size, '#'); ret = IsCompleteBinTree(pRoot); } int main() { testBinTree(); system("pause"); return 0; }
///////////////////////////////////////////////////分(结)隔(束)符//////////////////////////////////////////////////////////////