二分木の基本操作

この記事には、バイナリ ツリーの基本的な操作を紹介するコードのみが含まれています。

大きな問題なくデバッグできました。
間違いがあれば批判して修正してください。

1. バイナリ ツリーのバイナリ リンク リスト ストレージ表現:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef int Status;
typedef int TElemType;

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

/* 二叉树的二叉链表储存表示 */
typedef struct BiTNode
{
	TElemType data;
	struct BiTNode* lchild, * rchild;/* 左右孩子指针 */
}BiTNode, *BiTree;

2 番目に、バイナリ ツリーの基本的な操作:

//函数声明
Status InitBiTree(BiTree* T);/* 构造空二叉树InitBiTree(&T) */

Status DesTroyBiTree(BiTree* T);/* 销毁二叉树DesTroyBiTree(&T) */

Status CreateBiTree(BiTree* T);/* 构造二叉树CreateBiTree(&T) */

Status ClearBiTree(BiTree* T);/* 清空二叉树ClearBiTree(&T) */

Status BiTreeEmpty(BiTree T);/* 判断二叉树是否为空BiTreeEmpty(T) */

int BiTreeDepth(BiTree T);/* 求二叉树的深度BiTreeDepth(T) */

BiTNode Root(BiTree T);/* 返回T的根结点Root(T) */

TElemType Value(BiTree T, BiTNode e);/* 返回e的值Value(T, e) */

Status Assign(BiTree T, BiTNode* e, TElemType value);/* 给结点e赋值Assign(T, &e, value) */

BiTNode* Parent(BiTree T, BiTNode e);/* 求e的双亲Parent(T, e) */

BiTNode* LeftChild(BiTree T, BiTNode e);/* 求e的左孩子LeftChild(T, e) */

BiTNode* RightChild(BiTree T, BiTNode e);/* 求e的右孩子RightChild(T, e) */

BiTNode* LeftSibling(BiTree T, BiTNode e);/* 求e的左兄弟LeftSibling(T, e) */

BiTNode* RightSibling(BiTree T, BiTNode e);/* 求e的右兄弟RightSibling(T, e) */

Status InsertChild(BiTree T, BiTNode* p, int LR, BiTree c);/* 插入子树InsertChild(T, p, LR, c) */

Status DeleteChild(BiTree T, BiTNode* p, int LR);/* 删除子树DeleteChild(T, p, LR) */

Status PreOrderTraverse(BiTree T, Status(*v)(TElemType e));/* 前序遍历子树PreOrderTraverse(T, visit()) */

Status InOrderTraverse(BiTree T, Status(*v)(TElemType e));/* 中序遍历子树InOrderTraverse(T, visit()) */

Status PostOrderTraverse(BiTree T, Status(*v)(TElemType e));/* 后序遍历子树PostOrderTraverse(T, visit()) */

Status visit(TElemType e);/* 输出值visit(e) */

BiTree NodePoint(BiTree T, TElemType data);/* 返回指定数据的结点NodePoint(T, data) */

/* 用队列实现层序遍历 */
Status LevelOrderTraverse(BiTree T, Status(*v)(TElemType e));/* 层序遍历子树LevelOrderTraverse(T, visit())*/

#define OVERFLOW -2

/* 链式队列,存放二叉树结点 */
typedef struct QNode {
	BiTNode* data;
	struct QNode* next;
}QNode, * QueuePtr;

/* 队列头指针、尾指针 */
typedef struct {
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

Status EnQueue(LinkQueue* Q, BiTNode* e);/* 插入e为队列的队尾元素EnQueue(&Q, e) */

Status DeQueue(LinkQueue* Q, BiTNode** e);/* 删除队列头元素DeQueue(&Q, &e) */

Status InitQueue(LinkQueue* Q);/* 构造一个空队列InitQueue(&Q) */

Status QueueEmpty(LinkQueue* Q);/* 判断队列是否为空QueueEmpty(&Q) */

1. 空のバイナリ ツリーを構築します。

/*---------------------------------------------------------------------------------------
功能:构造空二叉树
参数:1、树指针
输出:OK、ERROR
*/
/* 构造空二叉树InitBiTree(&T) */
Status InitBiTree(BiTree* T)
{
	(*T) = NULL;
	return OK;
}

2. バイナリ ツリーを破棄します。

/*---------------------------------------------------------------------------------------
功能:销毁二叉树
参数:1、树指针
输出:OK、ERROR
*/
/* 销毁二叉树DesTroyBitree(&T)*/
Status DesTroyBiTree(BiTree* T)
{
    if (*T)
    {
        DesTroyBiTree((*T)->lchild);
        DesTroyBiTree((*T)->rchild);
        free((*T));
        (*T) = NULL;
    }
    return OK;
}

3. バイナリ ツリーを構築します。

/*---------------------------------------------------------------------------------------
功能:构造二叉树
参数:1、树指针
输出:OK、ERROR
*/
/* 构造二叉树CreateBiTree(&T) */
Status CreateBiTree(BiTree* T)
{
    char data, temp;
    data = getchar();
    temp = getchar();
    if (data == '#')
    {
        (*T) = NULL;
        return OK;
    }
    else
    {
        (*T) = (BiTree)malloc(sizeof(BiTNode));
        if (*T)
        {
            (*T)->data = data;
            printf("请输入%c的左子树:>", data);
            CreateBiTree(&(*T)->lchild);
            printf("请输入%c的右子树:>", data);
            CreateBiTree(&(*T)->rchild);
        }
    }
    return OK;
}

4. バイナリ ツリーをクリアします。

/*---------------------------------------------------------------------------------------
功能:清空二叉树
参数:1、树指针
输出:OK、ERROR
*/
/* 清空二叉树ClearBiTree(&T) */
Status ClearBiTree(BiTree* T)
{
    if (!*T)
    {
        return ERROR;
    }
    ClearBiTree(&(*T)->lchild);
    ClearBiTree(&(*T)->rchild);
    free(*T);
    *T = NULL;
    return OK;
}

5. バイナリ ツリーが空かどうかを確認します。

/*---------------------------------------------------------------------------------------
功能:判断二叉树是否为空
参数:1、二叉树
输出:TRUE、FALSE
*/
/* 判断二叉树是否为空BiTreeEmpty(T) */
Status BiTreeEmpty(BiTree T)
{
    if (T)
    {
        return FALSE;
    }
    return TRUE;
}

6. バイナリ ツリーの深さを求めます。

/*---------------------------------------------------------------------------------------
功能:求二叉树的深度
参数:1、二叉树
输出:树的深度
*/
/* 求二叉树的深度BiTreeDepth(T) */
int BiTreeDepth(BiTree T)
{
    int Depth = 0;
    if (T)
    {
        int leftDepth = BiTreeDepth(T->lchild);
        int rightDepth = BiTreeDepth(T->rchild);
        Depth = leftDepth >= rightDepth ? leftDepth + 1 : rightDepth + 1;
    }
    return Depth;
}

7. T のルート ノードを返します。

/*---------------------------------------------------------------------------------------
功能:返回T的根结点
参数:1、二叉树
输出:T的根结点
*/
/* 返回T的根结点Root(T) */
BiTNode Root(BiTree T)
{
    return (*T);
}

8. e の値を返します。

/*---------------------------------------------------------------------------------------
功能:返回e的值
参数:1、树 2、结点
输出:元素值
*/
/* 返回e的值Value(T, e) */
TElemType Value(BiTree T, BiTNode e)
{
    return e.data;
}

9. ノード e に値を割り当てます。

/*---------------------------------------------------------------------------------------
功能:给结点e赋值
参数:1、二叉树 2、结点指针 3、元素值
输出:OK、ERROR
*/
/* 给结点e赋值Assign(T, &e, value) */
Status Assign(BiTree T, BiTNode* e, TElemType value)
{
    e->data = value;
    return OK;
}

10. e の親を見つけます。

/*---------------------------------------------------------------------------------------
功能:求e的双亲
参数:1、二叉树 2、结点
输出:结点指针
*/
/* 求e的双亲Parent(T, e) */
BiTNode* Parent(BiTree T, BiTNode e)
{
    if (T == NULL)
    {
        return NULL;
    }
    if (T)
    {
        if (T->data == e.data)
        {
            return NULL;
        }
    }
    if (T->lchild != NULL && T->lchild->data == e.data || T->rchild != NULL && T->rchild->data == e.data)
    {
        return T;
    }
    else
    {
        BiTNode* tempP = NULL;
        if (tempP = Parent(T->lchild, e))
        {
            return tempP;
        }
        if (tempP = Parent(T->rchild, e))
        {
            return tempP;
        }
    }
    return NULL;
}

11. e の左の子を見つけます。

/*---------------------------------------------------------------------------------------
功能:求e的左孩子
参数:1、二叉树 2、结点
输出:结点指针
*/
/* 求e的左孩子LeftChild(T, e) */
BiTNode* LeftChild(BiTree T, BiTNode e)
{
    BiTNode* p = NodePoint(T, e.data);
    if (p->lchild)
    {
        return p->lchild;
    }
    return NULL;
}

12. e の正しい子を見つけます:

/*---------------------------------------------------------------------------------------
功能:求e的右孩子
参数:1、二叉树 2、结点
输出:结点指针
*/
/* 求e的右孩子RightChild(T, e) */
BiTNode* RightChild(BiTree T, BiTNode e)
{
    BiTNode* p = NodePoint(T, e.data);
    if (p->rchild)
    {
        return p->rchild;
    }
    return NULL;
}

13. e の左の兄弟を見つけます。

/*---------------------------------------------------------------------------------------
功能:求e的左兄弟
参数:1、二叉树 2、结点
输出:结点指针
*/
/* 求e的左兄弟LeftSibling(T, e) */
BiTNode* LeftSibling(BiTree T, BiTNode e)
{
    if (T)
    {
        BiTNode* p = Parent(T, e);
        if (p->lchild && p->rchild && p->rchild->data == e.data)
        {
            return p->lchild;
        }
    }
    return NULL;
}

14. e の正しい兄弟を見つけます:

/*---------------------------------------------------------------------------------------
功能:求e的右兄弟
参数:1、二叉树 2、结点
输出:结点指针
*/
/* 求e的右兄弟RightSibling(T, e) */
BiTNode* RightSibling(BiTree T, BiTNode e)
{
    if (T)
    {
        BiTNode* p = Parent(T, e);
        if (p->lchild && p->rchild && p->lchild->data == e.data)
        {
            return p->rchild;
        }
    }
    return NULL;
}

15. サブツリーを挿入します。

/*---------------------------------------------------------------------------------------
功能:插入子树
参数:1、二叉树 2、结点 3、标志域 4、树结点
输出:OK、ERROR
*/
/* 插入子树InsertChild(T, p, LR, c) */
Status InsertChild(BiTree T, BiTNode* p, int LR, BiTree c)
{
    if (p)
    {
        if (LR == 0)
        {
            c->rchild = p->lchild;
            p->lchild = c;
        }
        else if (LR == 1)
        {
            c->rchild = p->rchild;
            p->rchild = c;
        }
        return OK;
    }
    return ERROR;
}

16. サブツリーを削除します。

/*---------------------------------------------------------------------------------------
功能:删除子树
参数:1、二叉树 2、结点 3、标志域
输出:OK、ERROR
*/
/* 删除子树DeleteChild(T, p, LR) */
Status DeleteChild(BiTree T, BiTNode* p, int LR)
{
    if (LR == 0) 
    {
        if (p->lchild) 
        {
            DesTroyBiTree(&p->lchild);
            return OK;
        }
    }
    if (LR == 1)
    {
        if (p->rchild)
        {
            DesTroyBiTree(&p->rchild);
            return OK;
        }
    }
    return ERROR;
}

17. サブツリーの事前順序走査:

/*---------------------------------------------------------------------------------------
功能:前序遍历子树
参数:1、二叉树 2、输出函数
输出:OK、ERROR
*/
/* 前序遍历子树PreOrderTraverse(T, visit()) */
Status PreOrderTraverse(BiTree T, Status(*v)(TElemType e))
{
    if (T)
    {
        if(visit(T->data))
            if(PreOrderTraverse(T->lchild, visit))
                if(PreOrderTraverse(T->rchild, visit))
                    return OK;
        return ERROR;
    }
    return OK;
}

18. サブツリーの順序トラバーサル:

/*---------------------------------------------------------------------------------------
功能:中序遍历子树
参数:1、二叉树 2、输出函数
输出:OK、ERROR
*/
/* 中序遍历子树InOrderTraverse(T, visit()) */
Status InOrderTraverse(BiTree T, Status(*v)(TElemType e))
{
    if (T)
    {
        if (InOrderTraverse(T->lchild, visit))
            if (visit(T->data))
                if (InOrderTraverse(T->rchild, visit))
                    return OK;
        return ERROR;
    }
    return OK;
}

19. サブツリーの事後走査:

/*---------------------------------------------------------------------------------------
功能:后序遍历子树
参数:1、二叉树 2、输出函数
输出:OK、ERROR
*/
/* 后序遍历子树PostOrderTraverse(T, visit()) */
Status PostOrderTraverse(BiTree T, Status(*v)(TElemType e))
{
    if (T)
    {
        if (PostOrderTraverse(T->lchild, visit))
            if (PostOrderTraverse(T->rchild, visit))
                if (visit(T->data))
                    return OK;
        return ERROR;
    }
    return OK;
}

20. サブツリーを階層順に走査します (補助キュー方式)。

/*---------------------------------------------------------------------------------------
功能:层序遍历子树
参数:1、二叉树 2、输出函数
输出:OK、ERROR
*/
/* 层序遍历子树LevelOrderTraverse(T, visit())*/
Status LevelOrderTraverse(BiTree T, Status(*v)(TElemType e))
{
    //初始化辅助队列
    LinkQueue lq;
    InitQueue(&lq);
    //头结点入队
    EnQueue(&lq, T);
    BiTree temp;
    //遍历
    while (!QueueEmpty(&lq))
    {
        //头结点出队
        DeQueue(&lq, &temp);
        //访问出队结点
        visit(temp->data);
        //左子树根节点入队
        if (temp->lchild != NULL)
        {
            EnQueue(&lq, temp->lchild);
        }
        //右子树根结点入队
        if (temp->rchild != NULL)
        {
            EnQueue(&lq, temp->rchild);
        }
    }
    return OK;
}

21. 出力値 (アクセス関数):

/*---------------------------------------------------------------------------------------
功能:输出值
参数:1、元素
输出:OK、ERROR
*/
/* 输出值visit(e) */
Status visit(TElemType e)
{
    printf("%c ", e);
    return OK;
}

22. 指定されたデータのノードを返します。

/*---------------------------------------------------------------------------------------
功能:返回指定数据的结点
参数:1、二叉树 2、数据
输出:结点指针
*/
/* 返回指定数据的结点NodePoint(T, data) */
BiTNode* NodePoint(BiTree T, TElemType data)
{
    if (T)
    {
        if (T->data == data)
        {
            return T;
        }
        BiTNode* node = NodePoint(T->lchild, data);
        if (node)
        {
            return node;
        }
        node = NodePoint(T->rchild, data);
        if (node)
        {
            return node;
        }
        else
        {
            return NULL;
        }
    }
    return NULL;
}

23. キューの末尾要素として e を挿入します。

/*---------------------------------------------------------------------------------------
功能:插入e为队列的队尾元素
参数:1、队列指针 2、元素
输出:OK、ERROR
*/
/* 插入e为队列的队尾元素EnQueue(&Q, e) */
Status EnQueue(LinkQueue* Q, BiTNode* e)
{
    QNode* p;
    p = (QNode*)malloc(sizeof(QNode));
    if (!p) exit(OVERFLOW);
    p->data = e;
    p->next = NULL;
    Q->rear->next = p;
    Q->rear = p;
    return OK;
}

24. キューのヘッド要素を削除します。

/*---------------------------------------------------------------------------------------
功能:删除队列头元素
参数:1、队列指针 2、元素
输出:OK、ERROR
*/
/* 删除队列头元素DeQueue(&Q, &e) */
Status DeQueue(LinkQueue* Q, BiTNode** e)
{
    QNode* p;
    if (Q->front == Q->rear)
        return ERROR;
    p = Q->front->next;
    *e = p->data;
    Q->front->next = p->next;
    if (Q->rear == p)
        Q->rear = Q->front;
    free(p);
    return OK;
}

25. 空のキューを構築します。

/*---------------------------------------------------------------------------------------
功能:构造一个空队列
参数:1、队列指针
输出:OK、ERROR
*/
/* 构造一个空队列InitQueue(&Q) */
Status InitQueue(LinkQueue* Q)
{
    Q->front = (QueuePtr)malloc(sizeof(QNode));//给头尾指针分配内存,让队列中的头尾指针指向同一个内存
    Q->rear = Q->front;
    if (!Q->front) exit(OVERFLOW);
    Q->front->next = NULL;
    return OK;
}

26. キューが空かどうかを確認します。

/*---------------------------------------------------------------------------------------
功能:判断队列是否为空
参数:1、队列指针
输出:OK、ERROR
*/
/* 判断队列是否为空QueueEmpty(&Q) */
Status QueueEmpty(LinkQueue* Q)
{
    if (Q->front->next == NULL)
        return TRUE;
    else
        return FALSE;
}

3. メインプログラムをテストします。

BiTree T;
BiTNode e, q;

int main()
{
	int Depth = 0;
	TElemType value = 0;

	InitBiTree(&T);                /* InitBiTree(&T) */

	if (CreateBiTree(&T))          /* CreateBiTree(&T) */
	{
		printf("创建成功!!!\n");
	}

	if (BiTreeEmpty(T))            /* BiTreeEmpty(T) */
	{
		printf("子树为空~\n");
	}
	else
	{
		printf("子树不为空!!!\n");
	}

	Depth = BiTreeDepth(T);        /* BiTreeDepth(T) */
	printf("树的深度为:%d\n", Depth);

	printf("前序遍历子树:");      /* PreOrderTraverse(T, visit) */
	PreOrderTraverse(T, visit);
	printf("\n");

	printf("中序遍历子树:");      /* InOrderTraverse(T, visit) */
	InOrderTraverse(T, visit);
	printf("\n");

	printf("后序遍历子树:");      /* PostOrderTraverse(T, visit) */
	PostOrderTraverse(T, visit);
	printf("\n");

	printf("层序遍历子树:");      /* LevelOrderTraverse(T, visit) */
	LevelOrderTraverse(T, visit);
	printf("\n");

	e = Root(T);                   /* Root(T) */
	printf("根结点的值为:");
	visit(e.data);
	printf("\n");

	e = Root(T);                   /* Value(T, e) */
	printf("当前e结点为根结点,其值为:%c\n", Value(T, e));

	e = *LeftChild(T, e);          /* LeftChild(T, e) */
	printf("e结点已改为根结点的左孩子!\n");
	printf("当前e结点的值为:%c\n", Value(T, e));

	e = *RightChild(T, e);         /* RightChild(T, e) */
	printf("e结点已改为根结点的左孩子的右孩子!\n");
	printf("当前e结点的值为:%c\n", Value(T, e));

	e = *LeftSibling(T, e);        /* LeftSibling(T, e) */
	printf("e结点已改为根结点的左孩子的右孩子的左兄弟!\n");
	printf("当前e结点的值为:%c\n", Value(T, e));

	e = *RightSibling(T, e);        /* RightSibling(T, e) */
	printf("e结点已改为根结点的左孩子的右孩子的左兄弟的右兄弟!\n");
	printf("当前e结点的值为:%c\n", Value(T, e));

	q = *Parent(T, e);             /* Parent(T, e) */
	printf("e结点双亲的值为:%c\n", Value(T, q));

	printf("输入要更改的值:>");
	value = getchar();             /* Assign(T, &e, value); */
	Assign(T, T, value);
	printf("前序遍历子树:");
	PreOrderTraverse(T, visit);
	printf("\n");

	if (ClearBiTree(&T))           /* ClearBiTree(&T) */
	{
		printf("清除成功!!!\n");
	}
	if (BiTreeEmpty(T))
	{
		printf("子树为空~\n");
	}
	else
	{
		printf("子树不为空!!!\n");
	}

	system("pause");
	return 0;
}

4. テスト結果:

 

おすすめ

転載: blog.csdn.net/absorb2601078490/article/details/125471354