二叉树

一、BTree.h

#ifndef __BTree_h__
#define __BTree_h__

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <Windows.h>

typedef int BTDataType;

typedef struct BinaryTreeNode
{
    struct BinaryTreeNode* _left; //左孩子
    struct BinaryTreeNode* _right; //右孩子
    BTDataType _data; //节点数据
}BTNode;

BTNode* BuyBTNode(BTDataType x);
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid);

void BTreePrevOrder(BTNode* root);
void BTreeInOrder(BTNode* root);
void BTreePostOrder(BTNode* root);
void BTreeLevelOrder(BTNode* root);

size_t BTreeSize(BTNode* root);
size_t BTreeLeafSize(BTNode* root);
size_t BTreeKLevelSize(BTNode* root, size_t k);
size_t BTreeDepth(BTNode* root);
BTNode* BTreeFind(BTNode* root, BTDataType x);

int IsCompleteBTree(BTNode* root);
int IsCompleteBTree1(BTNode* root);

void BTreePrevOrderNonR(BTNode* root);
void BTreeInOrderNonR(BTNode* root);
void BTreePostOrderNonR(BTNode* root);

#endif __BTree_h__

二、Queue.h

#ifndef __Queue_h__
#define __Queue_h__

#include "BTree.h"

typedef BTNode* QDataType;

typedef struct QueueNode
{
    QDataType _data;
    struct QueueNode* _next;
}QueueNode;

typedef struct Queue
{
    QueueNode* _head; //队头指针
    QueueNode* _tail; //队尾指针
}Queue;

//初始化
void QueueInit(Queue* q)
{
    assert(q);
    q->_head = q->_tail = (QueueNode*)malloc(sizeof(QueueNode));
    assert(q->_head&&q->_tail);
    q->_head->_next = NULL;
}

//销毁
void QueueDestroy(Queue* q)
{
    assert(q);
    while (q->_head)
    {
        q->_tail = q->_head->_next;
        free(q->_head);
        q->_head = q->_tail;
    }
}

//入队
void QueuePush(Queue* q, QDataType x)
{
    QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
    assert(newnode);
    newnode->_data = x;
    newnode->_next = NULL;
    q->_tail->_next = newnode;
    q->_tail = newnode;
}

//出队
void QueuePop(Queue* q)
{
    if (q->_head == q->_tail)
    {
        return;
    }
    QueueNode* next = q->_head->_next;
    q->_head->_next = next->_next;
    if (q->_tail == next)
    {
        q->_tail = q->_head;
    }
    free(next);
}

//获取队头元素
QDataType QueueFront(Queue* q)
{
    if (q->_head == q->_tail)
    {
        return NULL;
    }
    else
    {
        return q->_head->_next->_data;
    }
}

//判空
int QueueEmpty(Queue* q)
{
    if (q->_head == q->_tail)
    {
        return 1;
    }
    return 0;
}

#endif __Queue_h__

三、stack.h

#ifndef __stack_h__
#define __stack_h__

#include "BTree.h"

#define Initsize 5 //初始存储空间
#define Increment 2 //每次增量

typedef BTNode* SDataType;

typedef struct Stack
{
    SDataType* _array;
    size_t _size; //有效数据个数 
    size_t _capacity; //容量 
}Stack;

//初始化
void StackInit(Stack* s)
{
    assert(s);
    s->_size = 0;
    s->_capacity = Initsize;
    s->_array = (SDataType*)malloc(Initsize*sizeof(SDataType));
    if (s->_array == NULL)
    {
        perror("StackInit");
        return;
    }
    memset(s->_array, 0, s->_capacity * sizeof(SDataType));
}

//扩容
void CheckCapacity(Stack* s)
{
    assert(s);
    if (s->_size >= s->_capacity)
    {
        SDataType* ptr = (SDataType*)realloc(s->_array, (s->_capacity + Increment)*sizeof(SDataType));
        if (ptr == NULL)
        {
            perror("CheckCapacity");
        }
        else
        {
            s->_array = ptr;
            s->_capacity += Increment;
        }
    }
}

//入栈
void StackPush(Stack* s, SDataType x)
{
    assert(s);
    CheckCapacity(s);
    s->_array[s->_size] = x;
    s->_size++;
}

//出栈
void StackPop(Stack* s)
{
    assert(s);
    if (s->_size == 0)
    {
        return;
    }
    else
    {
        s->_size--;
    }
}

//获取栈顶元素
SDataType StackTop(Stack* s)
{
    assert(s);
    if (s->_size == 0)
    {
        return NULL;
    }
    return s->_array[(s->_size) - 1];
}

//判空
int StackEmpty(Stack* s)
{
    assert(s);
    if (s->_size)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

#endif __stack_h__

四、BTree.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "BTree.h"
#include "Queue.h"
#include "stack.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) //
{
    BTNode* root = NULL;
    if (a[*pIndex] != invalid)
    {
        root = BuyBTNode(a[*pIndex]);
        (*pIndex)++;
        root->_left = CreateBTree(a, pIndex, invalid); //左递归
        (*pIndex)++;
        root->_right = CreateBTree(a, pIndex, invalid); //右递归
    }
    return root;
}

//先序遍历
void BTreePrevOrder(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    printf("%d ", root->_data); //访问根
    BTreePrevOrder(root->_left); //左递归
    BTreePrevOrder(root->_right); //右递归
}

//中序遍历
void BTreeInOrder(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    BTreeInOrder(root->_left); //左递归
    printf("%d ", root->_data); //访问根
    BTreeInOrder(root->_right); //右递归
}

//后序遍历
void BTreePostOrder(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    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))
    {
        QDataType first = QueueFront(&q);
        QueuePop(&q);
        printf("%d ", first->_data);
        if (first->_left)
        {
            QueuePush(&q, first->_left);
        }
        if (first->_right)
        {
            QueuePush(&q, first->_right);
        }
    }
}

//总节点数
//子问题:每棵树的节点数=该树的根节点(1)+左子树的节点数+右子树的节点数
size_t BTreeSize(BTNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    return 1 + BTreeSize(root->_left) + BTreeSize(root->_right);
}

//叶子节点数
//子问题:每棵树的叶子节点数=左子树的叶子节点数+右子树的叶子节点数
size_t BTreeLeafSize(BTNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    else if (root->_left == NULL&&root->_right == NULL)
    {
        return 1;
    }
    return BTreeLeafSize(root->_left) + BTreeLeafSize(root->_right);
}

//第K层节点数
//子问题:每棵树的第K层节点数=左子树的第k-1层节点数+右子树的第k-1层节点数
size_t BTreeKLevelSize(BTNode* root, size_t k)
{
    if (root == NULL)
    {
        return 0;
    }
    if (k == 1)
    {
        return 1;
    }
    return BTreeKLevelSize(root->_left, k - 1) + BTreeKLevelSize(root->_right, k - 1);
}

//深度
//子问题:每棵树的深度=左子树深度和右子树深度两者较大值+1
size_t BTreeDepth(BTNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    size_t LeftDepth = BTreeDepth(root->_left);
    size_t RightDepth = BTreeDepth(root->_right);
    return LeftDepth > RightDepth ? (LeftDepth + 1) : (RightDepth + 1);
}

//查找
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
    if (root == NULL)
    {
        return NULL;
    }
    if (root->_data == x)
    {
        return root;
    }
    BTNode* ret = BTreeFind(root->_left, x);
    if (ret)
    {
        return ret;
    }
    return BTreeFind(root->_right, x);
}

//判断完全二叉树 
int IsCompleteBTree(BTNode* root)
{
    if (root == NULL)
    {
        return 1;
    }
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q)) //找到队列里的第一个NULL
    {
        QDataType first = QueueFront(&q);
        if (first == NULL)
        {
            break;
        }
        QueuePop(&q);
        QueuePush(&q, first->_left);
        QueuePush(&q, first->_right);
    }
    while (!QueueEmpty(&q)) //从第一个NULL后,判断是否有非NULL值出现
    {
        QDataType first = QueueFront(&q);
        if (first) //若出现非NULL值,则为非完全二叉树
        {
            return 0;
        }
        QueuePop(&q);
    }
    return 1; //直到队列为空也没有出现非NULL值,则为完全二叉树
}

//判断完全二叉树,flag的方式判断 
int IsCompleteBTree1(BTNode* root)
{
    if (root == NULL)
    {
        return 1;
    }
    int flag = 0;
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q))
    {
        QDataType first = QueueFront(&q);
        QueuePop(&q);
        if (first->_left==NULL) //左子树
        {
            flag = 1;
        }
        else
        {
            if (flag == 1)
            {
                return 0;
            }
            QueuePush(&q, first->_left);
        }
        if (first->_right == NULL) //右子树
        {
            flag = 1;
        }
        else
        {
            if (flag == 1)
            {
                return 0;
            }
            QueuePush(&q, first->_right);
        }
    }
    return 1;
}

//非递归先序遍历
void BTreePrevOrderNonR(BTNode* root)
{
    Stack s;
    StackInit(&s);
    BTNode* cur = root;
    while (cur || StackEmpty(&s) != 0) 
        //如果cur非NULL,则说明当前节点未遍历;如果栈s不为空,则说明右子树未遍历;只有当两个都为0时,才说明整个树遍历完
    {
        while (cur)
        {
            printf("%d ", cur->_data);
            StackPush(&s, cur);
            cur = cur->_left;
        }
        BTNode* top = StackTop(&s);
        StackPop(&s);
        cur = top->_right;
    }
}

//非递归中序遍历
void BTreeInOrderNonR(BTNode* root)
{
    Stack s;
    StackInit(&s);
    BTNode* cur = root;
    while (cur || StackEmpty(&s) != 0)
    {
        while (cur)
        {
            StackPush(&s, cur);
            cur = cur->_left;
        }
        BTNode* top = StackTop(&s);
        printf("%d ", top->_data);
        StackPop(&s);
        cur = top->_right;
    }
}

//非递归后序遍历
void BTreePostOrderNonR(BTNode* root)
{
    Stack s;
    StackInit(&s);
    BTNode* cur = root;
    BTNode* last = NULL; //last记录上一次访问节点,作为右子树访问标记
    while (cur || StackEmpty(&s) != 0)
    {
        while (cur)
        {
            StackPush(&s, cur);
            cur = cur->_left;
        }
        BTNode* top = StackTop(&s);
        if (top->_right == last || top->_right == NULL) //如果top->_right == last,说明右子树上次已访问过
        {
            printf("%d ", top->_data);
            last = top; //更新last
            StackPop(&s);
        }
        else
        {
            cur = top->_right;
        }
    }
}

五、test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "BTree.h"

int main()
{
    //int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' };
    int a[] = { 1, 2, 3, '#', '#', '#', 5, 6, '#', '#', '#' };
    size_t index = 0;

    BTNode* tree = CreateBTree(a, &index, '#');
    printf("先序遍历:");
    BTreePrevOrder(tree);
    printf("\n");

    printf("非递归先序遍历:");
    BTreePrevOrderNonR(tree);
    printf("\n");

    printf("中序遍历:");
    BTreeInOrder(tree);
    printf("\n"); 

    printf("非递归中序遍历:");
    BTreeInOrder(tree);
    printf("\n");

    printf("后序遍历:");
    BTreePostOrder(tree);
    printf("\n");

    printf("非递归后序遍历:");
    BTreePostOrder(tree);
    printf("\n");

    printf("层序遍历:");
    BTreeLevelOrder(tree);
    printf("\n");

    printf("总节点数:%d\n", BTreeSize(tree));
    printf("叶子节点数:%d\n", BTreeLeafSize(tree));
    printf("第%d层节点数:%d\n", 2, BTreeKLevelSize(tree, 2));
    printf("深度:%d\n", BTreeDepth(tree));
    printf("是否为完全二叉树?%d\n", IsCompleteBTree(tree));
    printf("是否为完全二叉树?%d\n", IsCompleteBTree1(tree));

    if (BTreeFind(tree, 4))
    {
        printf("找到了\n");
    }
    else
    {
        printf("未找到\n");
    }

    system("pause");
    return 0;
}

程序执行结果:
(1)int a[] = { 1, 2, 3, ‘#’, ‘#’, 4, ‘#’, ‘#’, 5, 6, ‘#’, ‘#’, ‘#’ };
这里写图片描述

(2)int a[] = { 1, 2, 3, ‘#’, ‘#’, ‘#’, 5, 6, ‘#’, ‘#’, ‘#’ };
这里写图片描述

猜你喜欢

转载自blog.csdn.net/X_Perseverance/article/details/80082107