其中先中后遍历分别使用了递归和非递归两种算法实现,层序遍历借助了队列,非递归遍历借助了栈来实现。
BinaryTree.h
#pragma once #include<stdio.h> #include<Windows.h> #include<assert.h> typedef int BTDataType; size_t count = 0; typedef struct BinTreeNode { struct BinTreeNode* _left; struct BinTreeNode* _right; BTDataType data; }BTNode; #include"Queue.h" #include"TreeStack.h" //创建节点 BTNode* BuyBTNode(BTDataType x) { BTNode* Node = (BTNode*)malloc(sizeof(BTNode)); assert(Node); Node->data = x; Node->_left = NULL; Node->_right = NULL; return Node; } //创建二叉树 BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid) { if (a[*pIndex] == invalid) { (*pIndex)++; return NULL; } BTNode* Node = BuyBTNode(a[(*pIndex)++]); Node->_left = CreateBTree(a, pIndex, invalid); Node->_right = CreateBTree(a, pIndex, invalid); return Node; } //先序遍历 void BTreePrevOrder(BTNode* root) { if (root != NULL) { printf("%d ", root->data); BTreePrevOrder(root->_left); BTreePrevOrder(root->_right); } } //中序遍历 void BTreeInOrder(BTNode* root) { if (root != NULL) { BTreeInOrder(root->_left); printf("%d ", root->data); BTreeInOrder(root->_right); } } //后续遍历 void BTreePostOrder(BTNode* root) { if (root != NULL) { BTreePostOrder(root->_left); BTreePostOrder(root->_right); printf("%d ", root->data); } } //层序遍历 void BTreeLevelOrder(BTNode* root) { if (root == NULL) { return; } Queue q; QueueInit(&q); QueuePush(&q, root); while (QueueEmpty(&q)) { BTNode* b; b = QueueFront(&q); printf("%d ", b->data); if (b->_left != NULL) { QueuePush(&q, b->_left); } if (b->_right != NULL) { QueuePush(&q, b->_right); } QueuePop(&q); } } size_t BTreeSize(BTNode* root) //求结点个数 { if (root == NULL) { return 0; //这里不能用-1,会溢出size_t的范围 } return 1 + BTreeSize(root->_left) + BTreeSize(root->_right); } size_t BTreeLeafSize(BTNode* root) //求叶子节点个数 { if (root == NULL) return 0; if (root->_left == NULL&&root->_right== NULL) return 1; else return BTreeLeafSize(root->_left) + BTreeLeafSize(root->_right); } int BTreeKLevelSize(BTNode* root, size_t k) //求第K层节点个数 { if (k == 1) { return 1; } return BTreeKLevelSize(root->_left, k - 1) + BTreeKLevelSize(root->_right, k - 1); } size_t BTreeDepth(BTNode* root) //求二叉树深度 { if (root == NULL) { return 0; } return 1+(BTreeDepth(root->_left) > BTreeDepth(root->_right) ? BTreeDepth(root->_left) : BTreeDepth(root->_right)); } int IsCompleteBTree(BTNode* root)//判断一棵二叉树是否是完全二叉树 { if (root == NULL) { return 0; } Queue q; QueueInit(&q); QueuePush(&q, root); while (QueueFront(&q)!=NULL) { BTNode* b = QueueFront(&q); QueuePush(&q, b->_left); QueuePush(&q, b->_right); QueuePop(&q); } while (QueueEmpty(&q) != 0) { QueuePop(&q); if (QueueFront(&q) != NULL) { return 0; } } return 1; } void BTreePrevOrderNonR(BTNode* root) //非递归前序遍历二叉树 { if (root == NULL) { return; } Stack s; StackInit(&s, 20); BTNode* cur = root; while (cur != NULL || StackEmpty(&s) != 0) { while (cur != NULL) { StackPush(&s, cur); printf("%d ", cur->data); cur = cur->_left; } //此时左树已经走完 BTNode* ret = StackTop(&s); cur = ret->_right; StackPop(&s); } } void BTreeInOrderNonR(BTNode* root)//中序非递归遍历二叉树 { if (root == NULL) { return; } Stack s; StackInit(&s, 20); BTNode* cur = root; while (cur != NULL || StackEmpty(&s) != 0) { while (cur != NULL) { StackPush(&s, cur); cur = cur->_left; } //此时左树已经走完 BTNode* ret = StackTop(&s); printf("%d ", ret->data); cur = ret->_right; StackPop(&s); } } void BTreePostOrderNonR(BTNode* root)//后序非递归遍历二叉树 { if (root == NULL) { return; } Stack s; StackInit(&s,20); BTNode *cur = root; BTNode *last = NULL;//新定义一个last记录右孩子是否遍历过,遍历过则将top->_right赋给last while (cur || StackEmpty(&s)) { while (cur) { StackPush(&s, cur); cur = cur->_left; } BTNode *top = StackTop(&s); //如果此时发现top无右孩子或者右孩子已经被遍历过了,则直接输出top的data if (top->_right == NULL || last == top->_right) { printf("%d ", top->data); StackPop(&s); } else { //进行到这里说明top有右孩子且尚未遍历过 cur = top->_right; last = top->_right; } } } void TestBinaryTree() { int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' }; size_t index = 0; BTNode* tree = CreateBTree(a, &index, '#'); BTreeLevelOrder(tree); printf("\n"); printf("是否为完全二叉树:%d\n",IsCompleteBTree(tree)); BTreePrevOrderNonR(tree); printf("\n"); BTreeInOrderNonR(tree); printf("\n"); BTreePostOrderNonR(tree); }
—————————————————————————————————————————————
Queue.h
#include<stdio.h> #include<windows.h> #include<assert.h> typedef struct QueueNode { BTNode* _data; //链式队列 struct QueueNode* _next; }QueueNode; typedef struct Queue { QueueNode* _head;//队头指针 QueueNode* _tail;//队尾指针 }Queue; void QueueInit(Queue* q)//队列初始化 { q->_head = (QueueNode*)malloc(sizeof(QueueNode)); assert(q->_head); q->_tail = q->_head; q->_tail->_next = NULL; } void QueuePush(Queue* q, BTNode* node)//入队 { assert(q); QueueNode *newnode = (QueueNode*)malloc(sizeof(QueueNode)); assert(newnode); newnode->_data = node; newnode->_next = NULL; q->_tail->_next = newnode; q->_tail = newnode; } void QueuePop(Queue* q)//出队 { assert(q); if (q->_head == q->_tail) { return ; } QueueNode* p = q->_head->_next; q->_head = p; } BTNode* QueueFront(Queue* q)//取队头数据指针 { assert(q); if (q->_head == q->_tail) { return NULL; } return (q->_head->_next)->_data; } size_t QueueSize(Queue* q)//计算队列长度 { assert(q); if (q->_head == q->_tail) { return 0; } QueueNode *flag = q->_head->_next; size_t i = 0; while (flag != q->_tail) { flag = flag->_next; i++; } return i + 1; } int QueueEmpty(Queue* q)//判断队列是否为空 { assert(q); if (q->_head == q->_tail) { return 0; } return 1; }—————————————————————————————————————————————
TreeStack.h
#pragma once #include<stdio.h> #include<windows.h> #include<assert.h> #include<malloc.h> #define STACKINCREMENT 10 #define MAX_SIZE 100 typedef BTNode* DataType; typedef struct Stack { DataType* _st; size_t _size; size_t _capacity; //容量 }Stack; void StackInit(Stack *s, size_t capacity); void StackDestory(Stack *s); void StackPush(Stack *s, DataType x); void StackPop(Stack*s); DataType StackTop(Stack *s); size_t StackSize(Stack *s); size_t StackEmpty(Stack *s); void StackPush(Stack *s, DataType x); void StackInit(Stack *s, size_t capacity) //初始化 { assert(s && capacity>0); s->_st = (DataType *)malloc(sizeof(DataType)*capacity); assert(s->_st); s->_size = 0; s->_capacity = capacity; } void StackPush(Stack *s, DataType x) //入栈 { assert(s); if (s->_size == s->_capacity) { s->_capacity *= 2; s->_st = (DataType*)realloc(s->_st, sizeof(DataType)*s->_capacity); } s->_st[s->_size++] = x; } void StackPop(Stack*s) //出栈 { assert(s && s->_size > 0); --s->_size; } DataType StackTop(Stack *s) //取栈顶 { assert(s && s->_size > 0); return s->_st[s->_size - 1]; } size_t StackSize(Stack *s) //取栈元素个数 { assert(s); return s->_size; } size_t StackEmpty(Stack *s) //判空 { return s->_size; }————————————————————————————————————————————
main.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"BinaryTree.h" int main() { TestBinaryTree(); system("pause"); return 0; }