이진 트리 체인 저장소의 전면, 중간 및 후면 재귀 및 비재귀 순회 및 레이어 순서 순회 실현
1. 이진 트리의 연결 저장 구조
#define ElementType char
typedef struct BTNode{
ElementType data;
struct BTNode *left,*right;
}BTNode,*BinTree;
2. 이진 트리의 전위, 중위, 후위 재귀 순회
시간복잡도와 공간복잡도는 모두 O(n)
프롤로그
- 이진 트리가 비어 있으면 작동하지 않습니다.
- 비어 있지 않으면
- 먼저 루트 노드를 방문하십시오.
- 그런 다음 사전 순서대로 왼쪽 하위 트리를 순회합니다.
- 선주문에서 오른쪽 하위 트리 순회
void PreOderTraverse(BinTree T){
if(!T) return;
else {
printf("%c\t",T->data);
PreOderTraverse(T->left);
PreOderTraverse(T->right);
}
}
순서대로
- 이진 트리가 비어 있으면 작동하지 않습니다.
- 비어 있지 않으면
- 왼쪽 하위 트리의 중위 순회
- 루트 노드 방문
- 오른쪽 하위 트리의 중위 순회
void PreOderTraverse(BinTree T){
if(!T) return;
else {
printf("%c\t",T->data);
PreOderTraverse(T->left);
PreOderTraverse(T->right);
}
}
후속
- 이진 트리가 비어 있으면 작동하지 않습니다.
- 비어 있지 않으면
- 왼쪽 하위 트리의 후순위 순회
- 오른쪽 하위 트리의 후위 순회
- 루트 노드 방문
void PreOderTraverse(BinTree T){
if(!T) return;
else {
printf("%c\t",T->data);
PreOderTraverse(T->left);
PreOderTraverse(T->right);
}
}
입력 이진 트리는 다음과 같습니다.
테스트 실행
int main(void)
{
//创建二叉树
BinTree A = (BinTree)malloc(sizeof(struct BTNode));
A->data = 'A';
BinTree B = (BinTree)malloc(sizeof(struct BTNode));
B->data = 'B';
BinTree C = (BinTree)malloc(sizeof(struct BTNode));
C->data = 'C';
BinTree D = (BinTree)malloc(sizeof(struct BTNode));
D->data = 'D';
BinTree E = (BinTree)malloc(sizeof(struct BTNode));
E->data = 'E';
BinTree F = (BinTree)malloc(sizeof(struct BTNode));
F->data = 'F';
A->left = B;A->right = C;
B->left = D;B->right = E;
C->left = F;C->right = NULL;
D->left = NULL;D->right =NULL;
E->left = NULL;E->right =NULL;
F->left = NULL;F->right =NULL;
//前序遍历
printf("先序遍历:");
PreOderTraverse(A);
printf("\n");
//中序遍历
printf("中序遍历:");
InOderTraverse(A);
printf("\n");
//后序遍历
printf("后序遍历:");
PostOrderTraverse(A);
printf("\n");
//释放内存
free(A);
free(B);
free(C);
free(D);
free(E);
free(F);
return 0;
}
출력 결과:
3. 이진 트리의 비재귀 순회
순차 비재귀 순회를 달성하기 위해 스택의 체인 스토리지를 사용하는 순차 비재귀 순회
이진 트리 노드를 저장하는 스택의 체인 저장 구조, 빈 스택 생성, 비어 있음 판단, 팝핑 및 푸시
/*栈的结点结构*/
typedef struct SNode{
BinTree data;
struct SNode *next;
}*Stack;
/*创建空栈*/
Stack CreateStack(){
//创造头结点S,S不定义任何元素
Stack S = (Stack)malloc(sizeof(struct SNode));
S->next = NULL;
return S;
}
/*判断栈空不空*/
int IsEmpty(Stack S){
return (S->next == NULL);
}
/*入栈*/
void Push(Stack S,BinTree T){
Stack newone = (Stack)malloc(sizeof(struct SNode));
newone->data = T;
newone->next = S->next;
S->next = newone;
}
/*出栈*/
BinTree Pop(Stack S){
if (!S)
{
return NULL;
}else{
Stack tmp;BinTree T;
tmp = S->next;//获取要删除的结点
S->next = tmp->next;//更新栈顶的下一个结点地址
T = tmp->data;//获取被弹出的栈元素的值
free(tmp);//释放弹出的栈顶结点内存
return T;
}
}
이진 트리의 사전 주문 비재귀 순회
void InOrderTraverse(BinTree T){
Stack S = CreateStack();//创建有头结点的空栈的指针
BinTree p = T;//临时树结点
BinTree q;
while (p || !IsEmpty(S)) //树不空或者栈空
{
if (p)
{
Push(S,p);//将根结点的指针放入栈中
p = p->left;//查看左子树,遍历左子树
}else{
//如果左子树遍历完,则从栈弹出根结点的值,开始遍历右子树
q = Pop(S);
printf("%c\t",q->data);
p = q->right;
}
}
}
테스트 실행
//创建二叉树同上
//测试中序非递归遍历二叉树
printf("中序非递归遍历:\n");
InOrderTraverse(A);
출력은 다음과 같습니다.
4. 레벨 순서 순회
큐의 순차 저장 구조를 사용하여 실현되는 계층적 순회
이진 트리 노드를 저장하고, 빈 큐를 생성하고, 비어 있다고 판단하고, 큐에 들어가고, 큐에서 나가는 큐의 순차적인 저장 구조
/*定义队列的顺序存储结构*/
typedef struct QNode
{
BinTree DataArray[MaxSize];//存放二叉树结点地址的数组
int front,rear;//队头和队尾下标
/*当front = rear时,链表为空*/
}*Queue;
/*创建空队列*/
Queue CreateQ(){
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->front = Q->rear = -1;
return Q;
}
/*入队,尾加*/
void AddQ(Queue Q,BinTree bt){
if ((Q->rear+1)%MaxSize == Q->front) return; /* 判断队列是否满 */
Q->rear = (Q->rear+1)%MaxSize;
Q->DataArray[Q->rear] = bt;
}
/* 出队,头删 */
BinTree DeQ(Queue Q){
if (Q->front == Q->rear) //判断队列是不是空
{
printf("\nit is null.\n");
return NULL;
}else{
Q->front = (Q->front+1)%MaxSize;
BinTree bt = Q->DataArray[Q->front];
return bt;
}
}
/* 判断队列是否为空 */
int IsEmpty(Queue Q){
return (Q->front == Q->rear);
}
이진 트리의 레벨 순회
void LevelTraversal(BinTree T){
if(!T) return; //空二叉树
//创建空队列
Queue Q = CreateQ();
BinTree p;
//入队
AddQ(Q,T); //根结点进入队列
while (!IsEmpty(Q)) //队不为空则循环
{
//出队
p = DeQ(Q);
printf("%c\t",p->data);
if(p->left) AddQ(Q,p->left);
if(p->right) AddQ(Q,p->right);
}
}
테스트 실행
//测试层次非递归遍历二叉树
printf("层次非递归遍历:\n");
LevelTraversal(A);
결과는 그림에 나와 있습니다.