树是由一个或多个结点组成的有限集合,其中:
⒈必有一个特定的称为根(ROOT)的结点;
⒉剩下的结点被分成n>=0个互不相交的集合T1、T2、......Tn,而且, 这些集合的每一个又都是树。树T1、T2、......Tn被称作根的子树(Subtree)。
树的递归定义如下:(1)至少有一个结点(称为根)(2)其它是互不相交的子树
1.树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,如上图的树,其度为2;树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。
2.树的深度——组成该树各结点的最大层次。
3.森林——指若干棵互不相交的树的集合,如上图,去掉根结点A,其原来的二棵子树T1、T2、T3的集合{T1,T2,T3}就为森林;
4.有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树。
Bintree.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<malloc.h> #include<string.h> #include"queue.h" #include"stack.h" typedef char BTDataType; typedef struct BinTreeNode { BTDataType _data; struct BinTreeNode* _pLeft; struct BinTreeNode* _pRight; }BTNode, *PBTNode; void _CreateBintree(PBTNode* pRoot,const BTDataType* arr, int size, int* index,BTDataType invalid); void CreateBinTree(PBTNode* pRoot,const BTDataType* arr, int size, BTDataType invalid); PBTNode BuyBinTreeNode(BTDataType data); void PreOrder(PBTNode pRoot); PBTNode Copy(PBTNode pRoot); void DestroyBinTree(PBTNode* pRoot); void PreOrderNor(PBTNode pRoot);//前序遍历非递归 void PreOrderNor2(PBTNode pRoot);//前序遍历非递归2 void InOrder(PBTNode pRoot);//中序遍历 void PostOrder(PBTNode pRoot);//后序遍历 void LevelOrder(PBTNode pRoot);//层序遍历 int BintreeNodeSize(PBTNode pRoot);//结点个数 int BintreeLeafSize(PBTNode pRoot);//叶结点个数 int BintreeLevelNodesize(PBTNode pRoot,int k);//k层结点个数 int BintreeHigh(PBTNode pRoot);//二叉树高度 void swap(PBTNode *left, PBTNode *right); void MirrorBinTree(PBTNode pRoot);// 二叉树的镜像递归 void MirrorBinTreeNor(PBTNode pRoot);// 二叉树的镜像非递归
Bintree.c
#include"Bintree.h" PBTNode BuyBinTreeNode(BTDataType data) { PBTNode pNewNode = (PBTNode)malloc(sizeof(BTNode)); if (NULL == pNewNode) { assert(0);//0为假,打印一条错误信息,然后停止程序运行 return NULL; } pNewNode->_pLeft = NULL; pNewNode->_pRight = NULL; pNewNode->_data = data; return pNewNode; } void _CreateBintree(PBTNode* pRoot, const BTDataType* arr, int size, int* index ,BTDataType invalid) { assert(pRoot); assert(index); if (*index < size && invalid != arr[*index]) { //创建根节点 *pRoot = BuyBinTreeNode(arr[*index]); //创建左子树 ++(*index);//防止递归时索引回退,应优先向后走 _CreateBintree(&(*pRoot)->_pLeft, arr, size, index,invalid); ++(*index);//防止递归时索引回退,应优先向后走 _CreateBintree(&(*pRoot)->_pRight, arr, size, index,invalid); //创建右子树 } } void CreateBinTree(PBTNode* pRoot,const BTDataType* arr, int size, BTDataType invalid) { int index = 0; _CreateBintree(pRoot, arr, size, &index, invalid); } PBTNode Copy(PBTNode pRoot) { PBTNode pNewNode = NULL; if (pRoot) { //拷贝根节点 pNewNode = BuyBinTreeNode(pRoot->_data); //拷贝左子数 if(pRoot->_pLeft)//判读是否有左子树,避免无效递归 pNewNode->_pLeft = Copy(pRoot->_pLeft); //拷贝右子树 if(pRoot->_pRight)//判读是否有右子树,避免无效递归 pNewNode->_pRight = Copy(pRoot->_pRight); } return pNewNode; } void DestroyBinTree(PBTNode* pRoot) { //不能按照前序遍历销毁,销毁根之后左右子树找不到 //应使用后续遍历销毁 assert(pRoot); if (*pRoot) { DestroyBinTree(&(*pRoot)->_pLeft); DestroyBinTree(&(*pRoot)->_pRight); free(*pRoot); *pRoot = NULL; } } void PreOrderNor(PBTNode pRoot)//前序遍历非递归 { Stack q; if (NULL == pRoot) { return; } StackInit(&q); StackPush(&q, pRoot); while (!StackEmpty(&q)) { PBTNode pCur = StackTop(&q); printf("%c", pCur->_data); StackPop(&q); if (pCur->_pRight) { StackPush(&q, pCur->_pRight); } if (pCur->_pLeft) { StackPush(&q, pCur->_pLeft); } } } void PreOrderNor2(PBTNode pRoot)//前序遍历非递归2 { Stack s; if (NULL == pRoot) { return; } StackInit(&s); StackPush(&s, pRoot); while(!StackEmpty(&s)) { PBTNode pCur = StackTop(&s); StackPop(&s); while (pCur) { printf("%c",pCur->_data); if (pCur->_pRight) StackPush(&s,pCur->_pRight); pCur = pCur->_pLeft; } } } void PreOrder(PBTNode pRoot)//前序 { if (pRoot) { printf("%c", pRoot->_data); PreOrder(pRoot->_pLeft); PreOrder(pRoot->_pRight); } } void InOrder(PBTNode pRoot)//中序遍历 { PreOrder(pRoot->_pLeft); printf("%c", pRoot->_data); PreOrder(pRoot->_pRight); } void PostOrder(PBTNode pRoot)//后序遍历 { if (pRoot) { PreOrder(pRoot->_pLeft); PreOrder(pRoot->_pRight); printf("%c", pRoot->_data); } } void LevelOrder(PBTNode pRoot) { //1取队头元素 //2访问 //3找到对头元素的左右子树入队列 //4队头出队列------循环,队列为空时终止 LQueue q; if (NULL == pRoot) { return; } InitQueue(&q); PushQueue(&q,pRoot); while(!QueueEmpyt(&q)) { PBTNode pCur = QueueFront(&q); printf("%c", pCur->_data); if (pCur->_pLeft) { PushQueue(&q,pCur->_pLeft); } if (pCur->_pRight) { PushQueue(&q, pCur->_pRight); } PopQueue(&q); } } int BintreeNodeSize(PBTNode pRoot) { if (NULL == pRoot) return 0; return BintreeNodeSize(pRoot->_pLeft) + BintreeNodeSize(pRoot->_pRight) + 1; } int BintreeLeafSize(PBTNode pRoot) { if (NULL == pRoot) return 0; if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight) return 1; return BintreeLeafSize(pRoot->_pLeft) + BintreeLeafSize(pRoot->_pRight) ; } int BintreeLevelNodesize(PBTNode pRoot,int k) { if (NULL == pRoot || k <= 0) return 0; if (k == 1) return 1; return BintreeLevelNodesize(pRoot->_pLeft, k - 1) + BintreeLevelNodesize(pRoot->_pRight,k - 1); } int BintreeHigh(PBTNode pRoot) { if (NULL == pRoot) return 0; int left = BintreeHigh(pRoot->_pLeft) + 1; int right = BintreeHigh(pRoot->_pRight) + 1; return left > right ? left : right; } void swap(PBTNode *left, PBTNode *right) { PBTNode tmp = *left; *left = *right; *right = tmp; } void MirrorBinTree(PBTNode pRoot)// 二叉树的镜像递归 { if (pRoot) { swap(&pRoot->_pLeft,&pRoot->_pRight); MirrorBinTree(pRoot->_pLeft); MirrorBinTree(pRoot->_pRight); } } void MirrorBinTreeNor(PBTNode pRoot)// 二叉树的镜像非递归 { LQueue q; if (NULL == pRoot) { return; } InitQueue(&q); PushQueue(&q, pRoot); while (!QueueEmpyt(&q)) { PBTNode pCur = QueueFront(&q); PopQueue(&q); if (pCur->_pLeft) { PushQueue(&q, pCur->_pLeft); } if (pCur->_pRight) { PushQueue(&q, pCur->_pRight); } swap(&pCur->_pLeft,&pCur->_pRight); } } void test() { const char* str = "ABD###CE##F"; PBTNode pRoot = NULL; PBTNode pNewNode = NULL; CreateBinTree(&pRoot,str, strlen(str),'#'); printf("PreOrder: "); PreOrder(pRoot); printf("\n"); printf("InOrder: "); InOrder(pRoot); printf("\n"); printf("PosteOrder: "); PostOrder(pRoot); printf("\n"); pNewNode = Copy(pRoot); printf("PreOrder pNewNode: "); PreOrder(pRoot); printf("\n"); printf("PreOrderNor: "); PreOrderNor(pRoot); printf("\n"); printf("PreOrderNor2: "); PreOrderNor2(pRoot); printf("\n"); printf("LevelOrder: "); LevelOrder(pRoot); printf("\n"); printf("结点个数为:%d\n", BintreeNodeSize(pRoot)); printf("叶子结点个数为: %d\n",BintreeLeafSize(pRoot)); printf("第3层结点个数为: %d\n", BintreeLevelNodesize(pRoot,3)); printf("二叉树高度: %d\n", BintreeHigh(pRoot)); printf("Mirror tree:"); MirrorBinTree(pRoot); PreOrder(pRoot); printf("\n"); printf("MirrorNor tree:"); MirrorBinTreeNor(pRoot); PreOrder(pRoot); printf("\n"); DestroyBinTree(&pRoot); DestroyBinTree(&pNewNode); } int main() { test(); system("pause"); return 0; }
stack.h
#pragma once #include<stdio.h> #include<stdlib.h> #define MAX_SIZE 100 extern struct BinTreeNode; typedef struct BinTreeNode* DataType; typedef struct Stack { DataType _arr[MAX_SIZE];//栈的元素最大个数 int _top;//栈顶 int _bottom;//栈低 int len;//栈大小 }Stack, *Pstack; // 栈的初始化 void StackInit(Stack* s); // 入栈 void StackPush(Stack* s, DataType data); // 出栈 void StackPop(Stack* s); // 获取栈顶元素 DataType StackTop(Stack* s); // 获取栈中元素个数 int StackSize(Stack* s); // 检测栈是否为空 int StackEmpty(Stack* s);
stack.c
#include"stack.h" void StackInit(Stack* S) { S->_bottom = S->_top = 0; S->len = 0; } void StackPush(Stack* S, DataType data) { if (S->len == MAX_SIZE) { printf("栈满溢出,添加失败!\n"); return; } S->_top++; S->_arr[S->_top] = data; S->len++; } void StackPop(Stack* S) { if (S->len == 0) { printf("栈为空!\n"); return; } S->_top--; S->len--; } DataType StackTop(Stack* S) { if (S->len == 0) { printf("栈为空!\n"); return; } return S->_arr[S->_top]; } int StackSize(Stack* S) { int ret = 0; ret = printf("栈中元素个数为:%d\n", S->len); return ret; } int StackEmpty(Stack* S) { if (S->len == 0) { return 1; } else { return 0; } }
queue.h
#pragma once extern struct BinTreeNode; typedef struct BinTreeNode* pData; #define DataType pData typedef struct Node { DataType data; struct Node * next; }qNode; //基于带头结点的单链表队列 typedef struct Queue { qNode * front; qNode * tail; }LQueue; void InitQueue(LQueue *queue); void PushQueue(LQueue *queue, DataType data); void PopQueue(LQueue * queue); DataType QueueFront(LQueue* queue); int QueueSize(LQueue* queue); int QueueEmpyt(LQueue* queue); void DestoryQueue(LQueue** queue);
queue.c
#include "queue.h" #include <assert.h> #include <malloc.h> #include <stdio.h> qNode * BuyNode(DataType data) { qNode * new = (qNode*)malloc(sizeof(qNode)); if (NULL == new) { printf("分配失败"); return NULL; } new->data = data; new->next = NULL; return new; } void InitQueue(LQueue *queue) { assert(queue); //创建头结点 qNode * head = BuyNode(0); queue->front = head; queue->tail = head; } void PushQueue(LQueue *queue, DataType data) { qNode *new = BuyNode(data); queue->tail->next = new; queue->tail = new; } void PopQueue(LQueue * queue) { qNode *pDel = queue->front->next; //不是空队列 if (pDel) { //除头结点只有一个结点 if (NULL == pDel->next) { queue->tail = queue->front; } queue->front->next = pDel->next; } } DataType QueueFront(LQueue* queue) { if (queue->front->next) { return queue->front->next->data; } return queue->front->data; } int QueueSize(LQueue* queue) { int count = 0; qNode * pcur = queue->front->next; while (pcur) { count++; pcur = pcur->next; } return count; } int QueueEmpyt(LQueue* queue) { if (queue->front == queue->tail) { return 1; } return 0; } void DestoryQueue(LQueue** queue) { if (*queue != NULL) { while ((*queue)->front) { PopQueue(*queue); } free(*queue); *queue = NULL; } }
树是由一个或多个结点组成的有限集合,其中: