데이터 구조-바이너리 트리 | 단서의 이진 트리 이해 및 구현

n 노드가있는 바이너리 트리의 경우 :
2 * n 포인터 필드가 있습니다.

그것에 해당하는 n-1 포인터 분기가 있습니다.

비어있는 n + 1 포인터 필드가 있습니다 (잎에 있거나 완전한 이진 트리의 노드가 아님).

단서 바이너리 트리는 n + 1 개의 빈 체인 도메인을 사용하여 노드의 전임자와 후계자의 정보를 저장합니다.

해결책은 두 개의 플래그 필드를 추가하는 것입니다 : 왼쪽 플래그 ltag와 오른쪽 플래그 rtag.
이때 단서 바이너리 트리의 노드 구조는 다음과 같습니다 :
lchild ltag data rtag rchild

여기서
ltag 0 노드의 좌측 자식에 참조하는 것이 1 인 경우, 상기 노드의 이전 지칭

rtag가 0이면 노드의 오른쪽 자식을 가리키고, 1이면 노드의 후속 항목을 가리 킵니다.

단서의 본질은 이진 트리의 널 포인터를 전임자 또는 후계자에 대한 단서로 변경하는 것입니다. 이 프로세스는 이진 트리를 탐색 할 때 얻습니다.

——————————————————————————————————————
// pre는 항상 프로세스의 노드 이전 트리 중 하나 (순회에 따른 순서)
// 프리가 전면에 있고 트리가 후면에 있으므로
먼저 트리의 왼쪽 자식이 프리 노드를 가리 키도록
만들고 // 트리 노드에 대한 pre point의 오른쪽 자식
// traversing 트리는 프로세스 중에 계속 변경되고 pre도 변경됩니다.

// 처음에는 이중 연결 목록을 생성하는 방법을 이해하지 못했습니다.

可以这样思考   我们输入时是以二叉树的顺序输入
然后遍历时有着不一样的顺序 
这个时候已经可以根据不一样的遍历方式根据A点找到其他点(而非拘泥于输入时候的顺序)
那么这些点又重新建立了关系

但这些关系是单向的


加上线索的原因就是使这些新的关系变为双向的
从而变为了双向链表!!!

여기에 사진 설명 삽입

比如这里输入的顺序是A B C D E F G
这也是前序遍历的顺序

여기에 사진 설명 삽입

但中序遍历可以得到B D C E A F G这样的顺序

여기에 사진 설명 삽입

同理 后序遍历也是如此

노드의 전임자와 후계자는 다른 순회 규칙에 따라 다를 수 있습니다.
사전 주문, 중간 주문 및 후 주문에 해당하는 단서의 이진 트리를 사전 큐 바이너리 트리, 중간 주문 큐 바이너리 트리라고합니다. 후속 큐 바이너리 트리.

	//pre始终在过程中的结点tree的前一个(顺序是按照遍历的来) 
	//既然pre在前  tree在后
	//那么先使tree的左孩子指向pre结点
	//再使得pre的右孩子指向tree结点

	//在遍历的过程中tree一直变化,  pre也在变化
	//刚开始没有理解双向链表如何生成 看图可以推一下
#include<iostream>
using namespace std;
typedef int Status;
typedef char elementype;

typedef enum {
    
    Link,thread}Pointertag;//枚举类型  第一个不声明的话就为1,后面依次增加

typedef struct TBree
{
    
    
	elementype data;
	struct TBree *lchild, *rchild;
	Pointertag ltag, rtag;
}*TB_NODE,BNODE;

//中序线索二叉树
Status InitThread_mid(TB_NODE &tree,TB_NODE &pre)
{
    
    
	if (tree == NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		InitThread_mid(tree->lchild,pre);

		if (!tree->lchild)//如果某元素的左孩子不存在的话,则使pre为其它的前驱   使得遍历顺序直接能用指针找到
		{
    
    
			tree->ltag = thread;
			tree->lchild = pre;
		}
		if (pre->rchild == NULL)//如果前驱元素的右孩子不存在的话,使其右孩子指向下一个  即建立后继
		{
    
    
			pre->rtag = thread;
			pre->rchild = tree;
		}
		pre = tree;//保持pre为   前面的元素
		//这里原为中序遍历的输出

		InitThread_mid(tree->rchild,pre);
	}
	return 0;
}
//前序线索二叉树
Status InitThread_before(TB_NODE &tree, TB_NODE &pre)
{
    
    
	if (tree == NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		if (tree->lchild == NULL)//建立该结点的前驱
		{
    
    
			tree->ltag = thread;
			tree->lchild = pre;
		}
		if (pre->rchild == NULL)//建立前驱的后继
		{
    
    
			pre->rtag = thread;
			pre->rchild = tree;
		}
		pre = tree;
		InitThread_before(tree->lchild, pre);
		InitThread_before(tree->rchild,pre);
	}
	return 0;
}
//后续线索二叉树
Status Initthread_after(TB_NODE &tree, TB_NODE &pre)
{
    
    
	if(tree == NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		Initthread_after(tree->lchild, pre);
		Initthread_after(tree->rchild,pre);

		if (tree->lchild == NULL)
		{
    
    
			tree->ltag = thread;
			tree->lchild = pre;
		}
		if (pre->rchild == NULL)
		{
    
    
			pre->rtag = thread;
			pre->rchild = tree;
		}
		pre = tree;
	}
}
//当有了线索之后,二叉树可以被认为是一个双向链表

이진 트리의 체인 표현 | 사전 주문 출력 | 후속 출력 | 순차 출력 | 파괴 및 기타 작업

N 진 트리 순차 저장 구조 + 연결 목록의 자식에 대한 부모 표현 | 데이터 구조 트리 | C ++ 구현

추천

출처blog.csdn.net/weixin_46096297/article/details/112149329