国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

這篇具有很好參考價值的文章主要介紹了二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

目錄

一、以下是我們需要實(shí)現(xiàn)的功能

二、以下是我們具體功能的實(shí)現(xiàn)

1.創(chuàng)建新的結(jié)點(diǎn)

2.通過數(shù)組生成二叉樹

?3.先序遍歷

4.中序遍歷

5.后序遍歷?

?6.層序遍歷

7.計算二叉樹的結(jié)點(diǎn)個數(shù)

8.查找指定值為x的結(jié)點(diǎn)

9.查找第K層的結(jié)點(diǎn)個數(shù)

10.統(tǒng)計二叉樹葉子結(jié)點(diǎn)的個數(shù)

11.判斷是否為完全二叉樹

12.二叉樹的銷毀

13.求二叉樹的高度

14.匯總

三、測試代碼


一、以下是我們需要實(shí)現(xiàn)的功能

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef char BTDataType;

typedef struct BinaryTreeNode
{
    BTDataType _data;
    struct BinaryTreeNode* _left;
    struct BinaryTreeNode* _right;
}BTNode;

BTNode* BuyNode(BTDataType x);

// 通過前序遍歷的數(shù)組"ABD##E#H##CF##G##"構(gòu)建二叉樹
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
// 二叉樹銷毀
void BinaryTreeDestroy(BTNode** root);
// 二叉樹節(jié)點(diǎn)個數(shù)
int BinaryTreeSize(BTNode* root);
// 二叉樹葉子節(jié)點(diǎn)個數(shù)
int BinaryTreeLeafSize(BTNode* root);
// 二叉樹第k層節(jié)點(diǎn)個數(shù)
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉樹查找值為x的節(jié)點(diǎn)
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉樹前序遍歷
void BinaryTreePrevOrder(BTNode* root);
// 二叉樹中序遍歷
void BinaryTreeInOrder(BTNode* root);
// 二叉樹后序遍歷
void BinaryTreePostOrder(BTNode* root);
// 層序遍歷
void BinaryTreeLevelOrder(BTNode* root);
// 判斷二叉樹是否是完全二叉樹
int BinaryTreeComplete(BTNode* root);

二、以下是我們具體功能的實(shí)現(xiàn)

1.創(chuàng)建新的結(jié)點(diǎn)

在下面的代碼中,我們將調(diào)用我們的創(chuàng)建新的結(jié)點(diǎn)來快速創(chuàng)建結(jié)點(diǎn)。

TNode* BuyNode(BTDataType x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    assert(node);

    node->_data = x;
    node->_left = NULL;
    node->_right = NULL;

    return node;
}

2.通過數(shù)組生成二叉樹

BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
//這里我們的a為我們的數(shù)組
//n為我們數(shù)組的最大長度
//pi為我們遍歷數(shù)組的指針。
//這里我們使用'#'來表示NULL
//當(dāng)我們所指向的位置的元素為#或者我們的指針已經(jīng)超出了數(shù)組的范圍的時候,我們就需要返回NULL
//并且將我們的指針后移。
    if(a[*pi] == '#' || *pi >= n)
    {
        printf("NULL ");
        (*pi)++;
        return NULL;
    }
//創(chuàng)建一個新的二叉樹的結(jié)點(diǎn)
    BTNode *dst= BuyNode(a[*pi]);
    printf("%c ",dst->_data);
    (*pi)++;
//將我們之前開創(chuàng)的結(jié)點(diǎn)的左右指針指向數(shù)組中所對應(yīng)的結(jié)點(diǎn)
//如果我們的對應(yīng)數(shù)組中的數(shù)據(jù)不為空的話,我們的左右指針都會指向新的對應(yīng)的結(jié)點(diǎn)
//如果我們的結(jié)點(diǎn)為空的話,我們會得到的返回值為NULL,
    dst->_left = BinaryTreeCreate(a,n,pi);
    dst->_right = BinaryTreeCreate(a,n,pi);

    return dst;
}

?就如我們在下面的代碼中的數(shù)組,我們按照上面先序遍歷的代碼的描述,我們所創(chuàng)建出來的就是這樣一棵二叉樹二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

?3.先序遍歷

先序遍歷就是先遍歷我們的根節(jié)點(diǎn),然后遍歷我們左子樹,然后遍歷我們的右子樹。

//先序遍歷
void BinaryTreePrevOrder(BTNode* root)
{
//如果我們根節(jié)點(diǎn)的等于NULL,我們就直接返回上一層遞歸
    if(root == NULL)
    {
        return;
    }
//將我們當(dāng)前結(jié)點(diǎn)中的數(shù)據(jù)打印出來
    printf("%c ",root->_data);
//遍歷我們的左樹
    BinaryTreePrevOrder(root->_left);
//遍歷我們的右樹
    BinaryTreePrevOrder(root->_right);
}

我們上面代碼進(jìn)行先序遍歷所生成的序列是這樣的

二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

?二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

4.中序遍歷

中序遍歷就是先讀取我們左子樹中的元素,再讀取我們根節(jié)點(diǎn)的元素,最后再讀取右子樹中的元素。

// 二叉樹中序遍歷
void BinaryTreeInOrder(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }
    BinaryTreeInOrder(root->_left);
    printf("%c ",root->_data);
    BinaryTreeInOrder(root->_right);
}

二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

?二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

5.后序遍歷?

后序遍歷就是先遍歷我們的左子樹,再遍歷我們右子樹,最后遍歷我們的根節(jié)點(diǎn)

void BinaryTreePostOrder(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }
    BinaryTreePostOrder(root->_left);
    BinaryTreePostOrder(root->_right);
    printf("%c ",root->_data);
}

從下面的順序中,我們發(fā)現(xiàn)我們最后才遍歷了根節(jié)點(diǎn)?

二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

?二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

?6.層序遍歷

層序遍歷就是先將我們二叉樹的根節(jié)點(diǎn)入隊,然后再將我們根節(jié)點(diǎn)的左右指針?biāo)赶虻慕Y(jié)點(diǎn)入隊,然后將我們隊首的元素出隊。

這里我們需要用到一個隊列,具體的隊列的代碼我們在下面的匯總代碼中將會給出。

// 層序遍歷
void BinaryTreeLevelOrder(BTNode* root)
{
//創(chuàng)建我們的隊列
    Queue q;
//初始化隊列
    QueueInit(&q);
    assert(root);
//將我們的根節(jié)點(diǎn)入隊列
    QueuePush(&q, root);
//如果我們的??臻g不為空的話就繼續(xù)我們的循環(huán)
    while(!QueueEmpty(&q))
    {
//創(chuàng)建一個臨時變量結(jié)點(diǎn)獲得我們隊列頭的結(jié)點(diǎn)
        BTNode *temp= QueueFront(&q);
//將我們隊列頭的數(shù)據(jù)打印
        printf("%c ",temp->_data);
//將我們隊列頭的左右指針?biāo)鶎?yīng)的結(jié)點(diǎn)入隊列
        if(temp->_left)
        {
            QueuePush(&q,temp->_left);
        }
        if(temp->_right)
        {
            QueuePush(&q,temp->_right);
        }
//將我們隊頭的結(jié)點(diǎn)出隊
        QueuePop(&q);
    }
//銷毀我們的隊伍
    QueueDestory(&q);
}

7.計算二叉樹的結(jié)點(diǎn)個數(shù)

// 二叉樹節(jié)點(diǎn)個數(shù)
int BinaryTreeSize(BTNode* root)
{
//如果我們當(dāng)前的結(jié)點(diǎn)為空,也就是說我們已經(jīng)到了葉子結(jié)點(diǎn)的左右結(jié)點(diǎn),也就是沒有結(jié)點(diǎn)
//所以我們需要返回0
    if(root==NULL)
    {
        return 0;
    }
//如果我們當(dāng)前的結(jié)點(diǎn)的左指針和右指針都是空的話,也就是說這是我們的葉子結(jié)點(diǎn)
//就返回1,也就是只有一個結(jié)點(diǎn)。
    if(root->_left==NULL&&root->_right==NULL)
    {
        return 1;
    }
//使用遞歸遍歷我們的二叉樹,即分別統(tǒng)計我們左子樹中的結(jié)點(diǎn)個數(shù)再加上右子樹中的結(jié)點(diǎn)個數(shù)再加上1
//因?yàn)槲覀冃枰獙⑽覀儺?dāng)前所指的結(jié)點(diǎn)算上。
    return BinaryTreeSize(root->_left)+BinaryTreeSize(root->_right)+1;
}

8.查找指定值為x的結(jié)點(diǎn)

這里我們的目的是找到第一個指定值為x的結(jié)點(diǎn),也就是說采用先序遍歷是最佳的方法。因?yàn)橄刃虮闅v會首先找到所對應(yīng)的結(jié)點(diǎn)然后將其返回,但是我們?nèi)绻捎闷渌谋闅v方式,由于先找到的不是根節(jié)點(diǎn)的元素,而是分別以左中右,和左右中的順序來遍歷,就會當(dāng)根結(jié)點(diǎn)為我們的1目標(biāo)結(jié)點(diǎn)時錯過我們的根節(jié)點(diǎn)。

// 二叉樹查找值為x的節(jié)點(diǎn)
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
    if(root==NULL)
    {
        return NULL;
    }
    if(root->_data==x)
    {
        return root;
    }
    BinaryTreeFind(root->_left, x);
    BinaryTreeFind(root->_right,x);
}

9.查找第K層的結(jié)點(diǎn)個數(shù)

查找第k層,我們將我們的問題化為小問題,也就是我們第一層的結(jié)點(diǎn)需要往下找k-1層,第二層的結(jié)點(diǎn)需要往下找k-2層,以此類推,只有當(dāng)我們的k為1的時候返回的就是我們需要找的k層的結(jié)點(diǎn)的個數(shù)的總和。

// 二叉樹第k層節(jié)點(diǎn)個數(shù)
int BinaryTreeLevelKSize(BTNode* root, int k)
{
    if(root==NULL)
    {
        return 0;
    }
    if(k==1)
    {
        return 1;
    }
//分別遍歷我們的左右子樹,并且將我們的k的參數(shù)--,當(dāng)我們的k為1時,就到達(dá)了我們所想要查找對應(yīng)的層。
    return BinaryTreeLevelKSize(root->_left, k-1)+BinaryTreeLevelKSize(root->_right, k-1);
}

10.統(tǒng)計二叉樹葉子結(jié)點(diǎn)的個數(shù)

// 二叉樹葉子節(jié)點(diǎn)個數(shù)
int BinaryTreeLeafSize(BTNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
//如果我們的結(jié)點(diǎn)的左右指針全部都為空,那就是我們的葉子結(jié)點(diǎn)
    if(root->_left==NULL&&root->_right==NULL)
    {
        return 1;
    }
//返回我們左子樹中的葉子結(jié)點(diǎn)和右子樹中的葉子結(jié)點(diǎn)之和
    return BinaryTreeLeafSize(root->_left)+BinaryTreeLeafSize(root->_right);
}

11.判斷是否為完全二叉樹

這里我們的主要思路就是通過采取類似層序遍歷的方法,找到我們?nèi)~子結(jié)點(diǎn)的下一層結(jié)點(diǎn)。

如果我們的二叉樹為一顆完全二叉樹,我們?nèi)~子結(jié)點(diǎn)的下一層結(jié)點(diǎn)中的全部結(jié)點(diǎn)應(yīng)該都是null,如果不是的話,就不是完全二叉樹。

// 判斷二叉樹是否是完全二叉樹
int BinaryTreeComplete(BTNode* root)
{
//如果我們的根節(jié)點(diǎn)是NULL就返回1表示是一棵完全二叉樹
    if(root==NULL)
    {
        return 1;
    }
//創(chuàng)建并且初始化我們的隊列
    Queue q;
    QueueInit(&q);
//將我們的根節(jié)點(diǎn)入隊
    QueuePush(&q,root);
//這里與我們層序遍歷的思路相同,但是我們需要找到我們層序遍歷中的最后一層
//也就是我們?nèi)~子結(jié)點(diǎn)的下一層
//如果我們的二叉樹是一棵完全二叉樹,我們的葉子結(jié)點(diǎn)的下一層應(yīng)該全部都是NULL
//在下面的第一個will中我們先找到我們?nèi)~子結(jié)點(diǎn)的下一層的第一個NULL結(jié)點(diǎn),然后跳出循環(huán)
    while(!QueueEmpty(&q))
    {
        BTNode *temp= QueueFront(&q);
        QueuePop(&q);
        if(temp==NULL)
        {
            break;
        }
        QueuePush(&q,temp->_left);
        QueuePush(&q,temp->_right);

    }
//在我們的第二個節(jié)點(diǎn)中,我們將繼續(xù)遍歷我們的棧,如果我們當(dāng)前棧中的全部全部結(jié)點(diǎn)都是NULL,
//那我們的二叉樹就是完全二叉樹,不然就不是
//如果是完全二叉樹的話,我們就返回1,不是的話我們就返回0
    while(!QueueEmpty(&q))
    {
        BTNode *temp= QueueFront(&q);
        QueuePop(&q);
        if(temp!=NULL)
        {
            printf("不是完全二叉樹\n");
            return 0;
        }
    }
    printf("是完全二叉樹\n");
    return 1;
}

對于我們上面所創(chuàng)建的二叉樹,我們可以從下面的圖中看出,我們經(jīng)過層次遍歷之后,我們找到了葉子結(jié)點(diǎn)的下一層結(jié)點(diǎn),當(dāng)我們讀取到null的時候,我們跳出了第一個循環(huán),進(jìn)入第二個循環(huán),在這第二個循環(huán)中,如果我們此時隊列中剩余的數(shù)據(jù)全部都是NULL,我們就能判斷這是一棵完全二叉樹,但是在下面的圖中,我們發(fā)現(xiàn)我們在讀取到了三個null之后,我們讀取到了H這個不為null的值,所以我們可以判斷我們當(dāng)前的這棵二叉樹不是完全二叉樹。?

?二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

?二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

12.二叉樹的銷毀

對于二叉樹的銷毀,采取后續(xù)遍歷的形式,先找到我們二叉樹中的左子樹和右子樹中的底層的結(jié)點(diǎn),(這里的底層指的是葉子結(jié)點(diǎn)那一層),然后將我們的葉子結(jié)點(diǎn)分別釋放空間,再一層層返回調(diào)用,自下而逐漸銷毀。

// 二叉樹銷毀
void BinaryTreeDestroy(BTNode** root)
{
    if(*root==NULL)
    {
        return;
    }
    BinaryTreeDestroy(&((*root)->_left));
    BinaryTreeDestroy(&((*root)->_right));
    free(*root);
    *root=NULL;
    return;
}

13.求二叉樹的高度

int BinaryTreeHeight(BTNode*root)
{
//如果我們的根節(jié)點(diǎn)為空的話,我們就直接返回
    if(root==NULL)
    {
        return 0;
    }
//如果我們找到了我們的葉子結(jié)點(diǎn),我們就返回1
    if(root->_right==NULL&&root->_left==NULL)
    {
        return 1;
    }
//遞歸調(diào)用,如果我們的左子樹的高度大于右子樹的高度,我們返回的數(shù)據(jù)就是左子樹的高度再加1
//這里的+1就是我們當(dāng)前層的結(jié)點(diǎn)
//如果我們的右子樹的高度大于我們左子樹的高度,我們返回的數(shù)據(jù)就是右子樹的高度再加1
    return (BinaryTreeHeight(root->_left)>=BinaryTreeHeight(root->_right) ? BinaryTreeHeight(root->_left)+1 :BinaryTreeHeight(root->_right)+1);
}

14.匯總

以下是我們寫在Btree.c中的全部代碼(含有二叉樹加上隊列的代碼)

#include "Btree.h"

BTNode* BuyNode(BTDataType x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    assert(node);

    node->_data = x;
    node->_left = NULL;
    node->_right = NULL;

    return node;
}


BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
    if(a[*pi] == '#' || *pi >= n)
    {
        printf("NULL ");
        (*pi)++;
        return NULL;
    }
    BTNode *dst= BuyNode(a[*pi]);
    printf("%c ",dst->_data);
    (*pi)++;

    dst->_left = BinaryTreeCreate(a,n,pi);
    dst->_right = BinaryTreeCreate(a,n,pi);

    return dst;
}


//先序遍歷
void BinaryTreePrevOrder(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }

    printf("%c ",root->_data);
    BinaryTreePrevOrder(root->_left);
    BinaryTreePrevOrder(root->_right);
}

// 二叉樹中序遍歷
void BinaryTreeInOrder(BTNode* root)
{
    BinaryTreePrevOrder(root->_left);
    if(root == NULL)
    {
        return;
    }

    printf("%c ",root->_data);
    BinaryTreePrevOrder(root->_right);
}

// 二叉樹后序遍歷
void BinaryTreePostOrder(BTNode* root)
{
    BinaryTreePrevOrder(root->_left);
    BinaryTreePrevOrder(root->_right);
    if(root == NULL)
    {
        return;
    }

    printf("%c ",root->_data);
}

// 層序遍歷
void BinaryTreeLevelOrder(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    assert(root);
    QueuePush(&q, root);
    while(!QueueEmpty(&q))
    {
        BTNode *temp= QueueFront(&q);
        printf("%c ",temp->_data);
        if(temp->_left)
        {
            QueuePush(&q,temp->_left);
        }
        if(temp->_right)
        {
            QueuePush(&q,temp->_right);
        }

        QueuePop(&q);
    }
    QueueDestory(&q);
}

// 二叉樹節(jié)點(diǎn)個數(shù)
int BinaryTreeSize(BTNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
    if(root->_left==NULL&&root->_right==NULL)
    {
        return 1;
    }
    return BinaryTreeSize(root->_left)+BinaryTreeSize(root->_right)+1;
}

// 二叉樹查找值為x的節(jié)點(diǎn)
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
    if(root==NULL)
    {
        return NULL;
    }
    if(root->_data==x)
    {
        return root;
    }
    BinaryTreeFind(root->_left, x);
    BinaryTreeFind(root->_right,x);
}

// 二叉樹第k層節(jié)點(diǎn)個數(shù)
int BinaryTreeLevelKSize(BTNode* root, int k)
{
    if(root==NULL)
    {
        return 0;
    }
    if(k==1)
    {
        return 1;
    }
    return BinaryTreeLevelKSize(root->_left, k-1)+BinaryTreeLevelKSize(root->_right, k-1);
}

// 二叉樹葉子節(jié)點(diǎn)個數(shù)
int BinaryTreeLeafSize(BTNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
    if(root->_left==NULL&&root->_right==NULL)
    {
        return 1;
    }
    return BinaryTreeLeafSize(root->_left)+BinaryTreeLeafSize(root->_right);
}

// 判斷二叉樹是否是完全二叉樹
int BinaryTreeComplete(BTNode* root)
{
    if(root==NULL)
    {
        return 1;
    }
    Queue q;
    QueueInit(&q);
    QueuePush(&q,root);
    while(!QueueEmpty(&q))
    {
        BTNode *temp= QueueFront(&q);
        QueuePop(&q);
        if(temp==NULL)
        {
            break;
        }
        QueuePush(&q,temp->_left);
        QueuePush(&q,temp->_right);

    }
    while(!QueueEmpty(&q))
    {
        BTNode *temp= QueueFront(&q);
        QueuePop(&q);
        if(temp!=NULL)
        {
            printf("不是完全二叉樹\n");
            return 0;
        }
    }
    printf("是完全二叉樹\n");
    return 1;
}
// 二叉樹銷毀
void BinaryTreeDestroy(BTNode** root)
{
    if(root==NULL)
    {
        return ;
    }
    if(*root==NULL)
    {
        return;
    }
    BinaryTreeDestroy(&((*root)->_left));
    BinaryTreeDestroy(&((*root)->_right));
    free(*root);
    *root=NULL;
    return;
}

//求二叉樹的高度
int BinaryTreeHeight(BTNode*root)
{
    if(root==NULL)
    {
        return 0;
    }
    if(root->_right==NULL&&root->_left==NULL)
    {
        return 1;
    }
    return (BinaryTreeHeight(root->_left)>=BinaryTreeHeight(root->_right) ? BinaryTreeHeight(root->_left)+1 :BinaryTreeHeight(root->_right)+1);
}

//隊列的創(chuàng)建
void QueueInit(Queue* pq)
{
    assert(pq);
    pq->head = pq->tail = NULL;
}

void QueueDestory(Queue* pq)
{
    assert(pq);
    QNode* cur = pq->head;
    while (cur)
    {
        QNode* next = cur->next;
        free(cur);
        cur = next;
    }

    pq->head = pq->tail = NULL;
}

void QueuePush(Queue* pq, QDataType x)
{
    assert(pq);
    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    assert(newnode);

    newnode->data = x;
    newnode->next = NULL;

    if (pq->tail == NULL)
    {
        assert(pq->head == NULL);
        pq->head = pq->tail = newnode;
    }
    else
    {
        pq->tail->next = newnode;
        pq->tail = newnode;
    }
}

void QueuePop(Queue* pq)
{
    assert(pq);
    assert(pq->head && pq->tail);

    if (pq->head->next == NULL)
    {
        free(pq->head);
        pq->head = pq->tail = NULL;
    }
    else
    {
        QNode* next = pq->head->next;
        free(pq->head);
        pq->head = next;
    }
}

bool QueueEmpty(Queue* pq)
{
    assert(pq);

    //return pq->head == NULL && pq->tail == NULL;
    return pq->head == NULL;
}

size_t QueueSize(Queue* pq)
{
    assert(pq);
    QNode* cur = pq->head;
    size_t size = 0;
    while (cur)
    {
        size++;
        cur = cur->next;
    }

    return size;
}

QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(pq->head);

    return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(pq->tail);

    return pq->tail->data;
}

以下是我們寫在Btree.h中的全部代碼(二叉樹再加上隊列的代碼)

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef char BTDataType;

typedef struct BinaryTreeNode
{
    BTDataType _data;
    struct BinaryTreeNode* _left;
    struct BinaryTreeNode* _right;
}BTNode;

BTNode* BuyNode(BTDataType x);

// 通過前序遍歷的數(shù)組"ABD##E#H##CF##G##"構(gòu)建二叉樹
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
// 二叉樹銷毀
void BinaryTreeDestroy(BTNode** root);
// 二叉樹節(jié)點(diǎn)個數(shù)
int BinaryTreeSize(BTNode* root);
// 二叉樹葉子節(jié)點(diǎn)個數(shù)
int BinaryTreeLeafSize(BTNode* root);
// 二叉樹第k層節(jié)點(diǎn)個數(shù)
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉樹查找值為x的節(jié)點(diǎn)
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉樹前序遍歷
void BinaryTreePrevOrder(BTNode* root);
// 二叉樹中序遍歷
void BinaryTreeInOrder(BTNode* root);
// 二叉樹后序遍歷
void BinaryTreePostOrder(BTNode* root);
// 層序遍歷
void BinaryTreeLevelOrder(BTNode* root);
// 判斷二叉樹是否是完全二叉樹
int BinaryTreeComplete(BTNode* root);
//求二叉樹的高度
int BinaryTreeHeight(BTNode* root);

typedef BTNode *QDataType;

typedef struct QueueNode
{
    QDataType data;
    struct QueueNode* next;
}QNode;

typedef struct Queue
{
    QNode* head;
    QNode* tail;

    //size_t size;
}Queue;

void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
bool QueueEmpty(Queue* pq);
size_t QueueSize(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);

三、測試代碼

以下是我們寫在test.c中的代碼

#include"Btree.h"
int main() {
    char a[17]={'A','B','D','#','#','E','#','H','#','#','C','F','#','#','G','#','#'};
    int b=0;
    int *pi=&b;
    BTNode *Btree=BinaryTreeCreate(a, 16, pi);
    printf("\n");
//前序遍歷
    BinaryTreePrevOrder(Btree);
    printf("\n");
//中序遍歷
    BinaryTreeInOrder(Btree);
    printf("\n");
//后序遍歷
    BinaryTreePostOrder(Btree);
    printf("\n");
    //乘次遍歷
    BinaryTreeLevelOrder(Btree);
    printf("\n");

    int number=BinaryTreeSize(Btree);
    printf("%d",number);
    printf("\n");
    //查找為x的結(jié)點(diǎn)
    BTNode *find=BinaryTreeFind(Btree, 'A');
    printf("%c\n",find->_data);

    //查詢第k層的結(jié)點(diǎn)個數(shù)
    int w=BinaryTreeLevelKSize(Btree, 3);
    printf("%d\n",w);

    //查詢?nèi)~子結(jié)點(diǎn)的個數(shù)
    int count=BinaryTreeLeafSize(Btree);
    printf("%d\n",count);

//判斷當(dāng)前是否為一棵完全二叉樹
    int r=BinaryTreeComplete(Btree);

    //求二叉樹的高度
    int x=BinaryTreeHeight(Btree);
    printf("二叉樹的高度是%d\n",x);
//    int c=fmax(2,1);
//    printf("%d\n",c);
//銷毀二叉樹
    BinaryTreeDestroy(&Btree);
    return 0;
}

以下是我們代碼的輸出結(jié)果

???????二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))文章來源地址http://www.zghlxwxcb.cn/news/detail-440568.html

到了這里,關(guān)于二叉樹的實(shí)現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)入門(C語言版)二叉樹的順序結(jié)構(gòu)及堆的概念及結(jié)構(gòu)實(shí)現(xiàn)應(yīng)用

    數(shù)據(jù)結(jié)構(gòu)入門(C語言版)二叉樹的順序結(jié)構(gòu)及堆的概念及結(jié)構(gòu)實(shí)現(xiàn)應(yīng)用

    普通的二叉樹是不適合用數(shù)組來存儲的,因?yàn)榭赡軙嬖诖罅康目臻g浪費(fèi)。而完全二叉樹更適合使用順序結(jié)構(gòu)存儲?,F(xiàn)實(shí)中我們通常把堆(一種二叉樹)使用 順序結(jié)構(gòu)的數(shù)組來存儲 ,需要注意的是 這里的堆和操作系統(tǒng)虛擬進(jìn)程地址空間中的堆是兩回事 ,一個是 數(shù)據(jù)結(jié)構(gòu) ,一

    2023年04月19日
    瀏覽(28)
  • 【C語言 數(shù)據(jù)結(jié)構(gòu)】二叉樹的遍歷

    【C語言 數(shù)據(jù)結(jié)構(gòu)】二叉樹的遍歷

    所謂先序遍歷二叉樹,指的是從根結(jié)點(diǎn)出發(fā),按照以下步驟訪問二叉樹的每個結(jié)點(diǎn): 訪問當(dāng)前結(jié)點(diǎn); 進(jìn)入當(dāng)前結(jié)點(diǎn)的左子樹,以同樣的步驟遍歷左子樹中的結(jié)點(diǎn); 遍歷完當(dāng)前結(jié)點(diǎn)的左子樹后,再進(jìn)入它的右子樹,以同樣的步驟遍歷右子樹中的結(jié)點(diǎn); 先序遍歷這棵二叉樹的過

    2024年02月04日
    瀏覽(23)
  • 【數(shù)據(jù)結(jié)構(gòu)】樹、二叉樹的概念和二叉樹的順序結(jié)構(gòu)及實(shí)現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)】樹、二叉樹的概念和二叉樹的順序結(jié)構(gòu)及實(shí)現(xiàn)

    之前我們學(xué)習(xí)了順序表、鏈表以及棧和隊列這些數(shù)據(jù)結(jié)構(gòu),但這些數(shù)據(jù)結(jié)構(gòu)都是線性的(一對一)。接下來要學(xué)習(xí) 非線性的數(shù)據(jù)結(jié)構(gòu)——樹(二叉樹) ,相比前面的,樹的結(jié)構(gòu)更加復(fù)雜,話不多說,直接進(jìn)入正題吧。 樹是一種 非線性的數(shù)據(jù)結(jié)構(gòu) ,它是 一對多(也有可能是

    2024年02月07日
    瀏覽(29)
  • 【數(shù)據(jù)結(jié)構(gòu)—二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實(shí)現(xiàn)】

    【數(shù)據(jù)結(jié)構(gòu)—二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實(shí)現(xiàn)】

    提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言 一、二叉樹的存儲結(jié)構(gòu) 二、二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn) 2.1手動構(gòu)建一課樹 2.2二叉樹的遍歷 三、二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn) 3.1前序遍歷(遞歸) 3.2中序遍歷(遞歸) 3.3后序遍歷(遞歸) 3.4層序遍歷(非遞

    2024年02月03日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu) —— 二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實(shí)現(xiàn)】

    【數(shù)據(jù)結(jié)構(gòu) —— 二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實(shí)現(xiàn)】

    樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),它是由n(n=0)個有限結(jié)點(diǎn)組成一個具有層次關(guān)系的集合。 把它叫做樹是因?yàn)樗雌饋硐褚豢玫箳斓臉?,也就是說它是根朝上,而葉朝下的。 1.有一個 特殊的結(jié)點(diǎn),稱為根結(jié)點(diǎn) ,根節(jié)點(diǎn)沒有前驅(qū)結(jié)點(diǎn) 2.除根節(jié)點(diǎn)外, 其余結(jié)點(diǎn)被分成M(M0)個互不相交

    2024年02月05日
    瀏覽(27)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的實(shí)現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的實(shí)現(xiàn)

    一棵二叉樹是結(jié)點(diǎn)的一個有限集合,該集合分為兩點(diǎn): 一是為空和二是由一個根節(jié)點(diǎn)加上兩棵別稱為左子樹和右子樹的二叉樹組成從圖上看出有2個性質(zhì): 二叉樹不存在度大于2的結(jié)點(diǎn) 二叉樹的子樹有左右之分,次序不能顛倒,因此二叉樹是有序樹 對于任意的二叉樹都是由以下

    2024年02月02日
    瀏覽(19)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的順序結(jié)構(gòu)及實(shí)現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的順序結(jié)構(gòu)及實(shí)現(xiàn)

    目錄 1. 二叉樹的順序結(jié)構(gòu) 2. 堆的概念及結(jié)構(gòu) 3. 堆的實(shí)現(xiàn) 3.1 堆向下調(diào)整算法 3.2 堆的創(chuàng)建 3.3 建堆時間復(fù)雜度 3.4 堆的插入 3.5 堆的刪除 3.6 堆的代碼實(shí)現(xiàn) 4. 堆的應(yīng)用 4.1 堆排序 4.2 TOP-K問題 普通的二叉樹是不適合用數(shù)組來存儲的,因?yàn)榭赡軙嬖诖罅康目臻g浪費(fèi)。而完全二叉

    2024年02月08日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu):二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)的實(shí)現(xiàn)

    ? 目錄 ?1.通過前序遍歷構(gòu)建二叉樹 2.?二叉樹的銷毀 ?3.二叉樹的遍歷 4.?二叉樹的節(jié)點(diǎn)個位和二叉樹的葉子節(jié)點(diǎn)個位數(shù) 5.?二叉樹的的k層節(jié)點(diǎn)數(shù)和查找值為x的節(jié)點(diǎn) 6.?判斷二叉樹是否為完全二叉樹和求二叉樹的高度h 二叉樹的前序遍歷 二叉樹的中序遍歷 二叉樹的后序遍歷

    2024年02月12日
    瀏覽(30)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)及實(shí)現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)及實(shí)現(xiàn)

    目錄 1. 前置說明 2. 二叉樹的遍歷 2.1 前序、中序以及后序遍歷 2.2 層序遍歷 3.?節(jié)點(diǎn)個數(shù)及高度等 4. 二叉樹的創(chuàng)建和銷毀 在學(xué)習(xí)二叉樹的基本操作前,需先要創(chuàng)建一棵二叉樹,然后才能學(xué)習(xí)其相關(guān)的基本操作。由于現(xiàn)在大家對二叉樹結(jié)構(gòu)掌握還不夠深入,為了降低大家學(xué)習(xí)成

    2024年02月08日
    瀏覽(25)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的前中后序遍歷(C語言)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的前中后序遍歷(C語言)

    [二叉樹] 顧名思義就是有 兩個分支節(jié)點(diǎn)的樹,不僅如此,除了葉子外的所有節(jié)點(diǎn)都具有兩個分支節(jié)點(diǎn); 由于結(jié)構(gòu)像一棵倒立的樹,顧名思義為二叉樹 ; 如下圖所示,該圖即為一棵 野生的二叉樹 ; 既然二叉樹為樹,固然有著和樹一樣的部分( 葉子、根、分支… ) 這些也成為

    2024年02月17日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包