数据结构复习:二叉树的链式存储实现

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

struct ElemType {
    int value;
};
typedef struct BiTNode {
    ElemType data;
    struct BiTNode *lchild, *rchild; // 左右孩子
    struct BiTNode *parent; //双亲
} BiTNode, *BiTree;

//初始化一颗空树
void InitBiTNode(BiTree &bt) {
    bt = NULL;
}

//左孩子
BiTNode *LeftChild(BiTNode *p) {
    return p->lchild;
}

//右孩子
BiTNode *RightChild(BiTNode *p) {
    return p->rchild;
}

//双亲
BiTNode *Parent(BiTNode *p) {
    return p->parent;
}
BiTNode *preNode = NULL,*tempPre = NULL;
BiTNode *nextNode = NULL;
bool  nextNodeFind = false;

BiTree p;

//查找前驱结点
void findPre(BiTNode *q) {
    if(preNode == NULL) {
        if(q->data.value == p->data.value) {
            preNode = tempPre;
            tempPre = NULL;
        } else {
            tempPre = q;
        }
    }
}

//查找后继结点
void findNext(BiTNode *q) {
    if(nextNodeFind) {
        nextNode = q;
        nextNodeFind = false;
    }
    if(q->data.value == p->data.value) {
        nextNodeFind = true;
    }
}

//访问当前元素
void visit(BiTNode *q) {
    printf("%d ", q->data);
    findPre(q);
    findNext(q);
}

//先序遍历递归实现
//访问顺序 根结点 左孩子 右孩子
void PreOrder(BiTree T) {
    if (T != NULL) { // 当前结点为空时候,结束
        visit(T);//先访问根结点
        PreOrder(T->lchild); // 访问左子树
        PreOrder(T->rchild);//访问右子树
    }
}



//中序遍历递归实现
//访问顺序 左孩子 根结点 右孩子
void InOrder(BiTree T) {
    if (T != NULL) { // 当前结点为空时候,结束
        InOrder(T->lchild); //先 访问左子树
        visit(T);//再访问根结点
        InOrder(T->rchild);//最后访问右子树
    }
}

//获取中序遍历序列时候某个结点的前驱和后继结点
void InOrderPreNext(BiTree T,BiTNode *p,BiTree &pre,BiTree &next,bool &preFound,bool &nextFound) {
    if (T != NULL) { // 当前结点为空时候,结束
        InOrderPreNext(T->lchild,p,pre,next,preFound,nextFound);//最后访问右子树
        if(preFound) {//如果前驱已经找到,那么下一个找到的是后继
            if(!nextFound) {
                next = T;
                nextFound = true;
            }
        } else{
            if(T->data.value == p->data.value) {//如果找到,则不再设置前驱,同时修改已经找到前驱的标志位为true
                preFound = true;
            } else {
                pre = T;//没找到,则前驱设置为当前结点
            }
        }
        visit(T);//再访问根结点
        InOrderPreNext(T->rchild,p,pre,next,preFound,nextFound);//最后访问右子树
    }
}


//后序遍历递归实现
//访问顺序 左孩子 右孩子 根结点
void PostOrder(BiTree T) {
    if (T != NULL) { // 当前结点为空时候,结束
        PostOrder(T->lchild); //先访问左子树
        PostOrder(T->rchild);//再访问右子树
        visit(T);//最后访问根结点
    }
}



//中序遍历非递归实现

//后序遍历非递归实现

//求树的深度
int BiTreeDepth(BiTree T) {
    int depth = 0;
    if (T != NULL) {
        depth++;//不为空树,当前深度+1
        int depth1 = BiTreeDepth(T->lchild);//获取左子树深度
        int depth2 = BiTreeDepth(T->rchild);//获取右子树深度
        int childDepth = depth1 >= depth2 ? depth1 : depth2;//左右子树的深度的最大值
        return depth + childDepth; //与当前深度相加
    } else {
        return 0;//空树,深度为0
    }
}


typedef struct LinkNode {
    BiTNode *data; // 存指针,而不是存结点
    struct LinkNode *next;
} LinkNode;

typedef struct {
    LinkNode *front, *rear;//队头,队尾
} LinkQueue;



//初始化空队列
void InitQueue(LinkQueue &Q) {
    Q.front = NULL;
    Q.rear = NULL;
}
//队列空
bool QueueEmpty(LinkQueue Q) {
    return Q.front == NULL;
}
//入队
bool EnQueue(LinkQueue &Q,BiTNode *T) {
    LinkNode *linkNode = (LinkNode*)malloc(sizeof(LinkNode));
    if(linkNode==NULL) {
        return false;
    }
    linkNode->data = T;
    linkNode->next = NULL;
    if(Q.rear == NULL) {//rear结点为空的时候,即空队列的时候
        Q.rear = linkNode;
    } else{ //非空队列时候,让将当前元素添加到rear指针指向结点的后面,然后让rear指针指向当前结点
        Q.rear->next = linkNode;
        Q.rear = linkNode;
    }
    if(Q.front == NULL) {//如果front结点为空,则front指针指向当前结点
        Q.front = linkNode;
    }
    return true;
}
//出队
bool DeQueue(LinkQueue &Q,BiTree &T) {
    if(QueueEmpty(Q)) {
        return false;
    }
    T = Q.front->data;
    Q.front = Q.front->next;//front执行指向 next结点
    if(Q.front == NULL){ //front执行变成了NULL,表面变成了空队列,则修改rear指针为空
        Q.rear = Q.front;
    }
    return true;
}
//不带头结点的链栈实现
typedef struct {
    LinkNode *top;//top指针指向栈顶
}LinkStack;
//初始化空栈
void InitStack(LinkStack &S) {
    S.top = NULL;
}
//栈空
bool StackEmpty(LinkStack S) {
    return S.top == NULL;
}
//入栈
bool Push(LinkStack &S,BiTNode *T) {
    LinkNode *linkNode = (LinkNode*)malloc(sizeof(LinkNode));
    if(linkNode==NULL) {
        return false;
    }
    linkNode->data = T;
    linkNode->next = S.top;
    S.top = linkNode;
}
//出栈
bool Pop(LinkStack &S,BiTree &T) {
    if(StackEmpty(S))
        return false;
    T = S.top->data;
    S.top = S.top->next;
    return true;
}

//层次遍历
void LevelOrder(BiTree T) {
    //初始化队列
    LinkQueue Q;
    InitQueue(Q);
    EnQueue(Q,T);//根结点入队
    while (!QueueEmpty(Q)) {
        BiTree node;
        DeQueue(Q,node); //当前树的根结点出队
        visit(node);//访问当树的根结点
        if(node->lchild!=NULL) {
            EnQueue(Q,node->lchild); //当前树的左子树不为空,左孩子入队
        }
        if(node->rchild!=NULL) {
            EnQueue(Q,node->rchild); //当前树的右子树不为空,右孩子入队
        }
    }
}


//前序遍历非递归实现
void PreOrderNoRecurrence(BiTree T) {
    LinkStack S;
    InitStack(S);
    Push(S,T);//根结点入栈
    while (!StackEmpty(S)) {
        BiTree T1;
        Pop(S,T1);
        visit(T1);//访问根结点
        if(T1->rchild != NULL) {
            Push(S,T1->rchild);
        }
        if(T1->lchild != NULL) {
            Push(S,T1->lchild);
        }
    }
}

//中序遍历非递归实现
void InOrderNoRecurrence(BiTree T) {


}

//后序遍历非递归实现
void PostOrderNoRecurrence(BiTree T) {

}

int main() {

    BiTree bt;
    InitBiTNode(bt);

    //插入根结点
    BiTNode *root = (BiTNode *) malloc(sizeof(BiTNode));
    root->data = {1};
    root->lchild = NULL;
    root->rchild = NULL;
    bt = root;
    printf("\n树的深度:%d\n", BiTreeDepth(bt));
    BiTNode *t1 = (BiTNode *) malloc(sizeof(BiTNode));
    t1->data = {6};
    t1->parent = root;
    root->lchild = t1;

    BiTNode *t11 = (BiTNode *) malloc(sizeof(BiTNode));
    t11->data = {3};
    t11->parent = t1;
    t1->lchild = t11;
    t11->lchild = NULL;
    t11->rchild = NULL;

    BiTNode *t12 = (BiTNode *) malloc(sizeof(BiTNode));
    t12->data = {9};
    t12->parent = t1;
    t1->rchild = t12;

    BiTNode *t121 = (BiTNode *) malloc(sizeof(BiTNode));
    t121->data = {8};
    t121->parent = t12;
    t12->lchild = t121;
    t121->lchild = NULL;
    t121->rchild = NULL;
    t12->rchild = NULL;

    BiTNode *t1211 = (BiTNode *) malloc(sizeof(BiTNode));
    t1211->data = {7};
    t1211->parent = t121;
    t121->lchild = t1211;
    t1211->lchild = NULL;
    t1211->rchild = NULL;
    t121->rchild = NULL;


    BiTNode *t2 = (BiTNode *) malloc(sizeof(BiTNode));
    t2->data = {13};
    t2->parent = root;
    root->rchild = t2;

    BiTNode *t21 = (BiTNode *) malloc(sizeof(BiTNode));
    t21->data = {11};
    t21->parent = t2;
    t2->lchild = t21;


    BiTNode *t211 = (BiTNode *) malloc(sizeof(BiTNode));
    t211->data = {10};
    t211->parent = t21;
    t21->lchild = t211;
    t211->lchild = NULL;
    t211->rchild = NULL;

    t21->rchild = NULL;

    BiTNode *t22 = (BiTNode *) malloc(sizeof(BiTNode));
    t22->data = {14};
    t22->parent = t2;
    t2->rchild = t22;
    t22->lchild = NULL;
    t22->rchild = NULL;

    p = t21;

    printf("\n先序遍历递归实现:\n");
    PreOrder(bt); // 1 6 3 9 8 7 13 11 10 14
    printf("\n中序遍历递归实现:\n");
    InOrder(bt); // 3 6 7 8 9 1 10 11 13 14
    printf("\n后序遍历递归实现:\n");
    PostOrder(bt); // 3 7 8 9 6 10 11 14 13 1
    printf("\n树的深度:%d\n", BiTreeDepth(bt));



    printf("层次遍历\n");
    LevelOrder(bt);


    printf("\n先序遍历非递归实现:\n");
    PreOrderNoRecurrence(bt);

    printf("\n中序遍历非递归实现:\n");
    InOrderNoRecurrence(bt);

    printf("\n后序遍历非递归实现:\n");
    PostOrderNoRecurrence(bt);

    BiTree pre = NULL,next = NULL;
    bool nextFound = false,preFound = false;
    BiTNode *q =t21;
    InOrderPreNext(bt,p,pre,next, preFound,nextFound);
    if(pre == NULL) {
        printf("\n当前结点:%d,后继结点:%d",q->data,next->data);
    }
    else if(next == NULL) {
        printf("\n当前结点:%d,前驱结点:%d",q->data,pre->data);
    } else {
        printf("\n当前结点:%d,前驱结点:%d,后继结点:%d",q->data,pre->data,next->data);
    }


    p =t11;
    p =t22;
    p = t1211;
    p = t1;
    p = root;
    preNode = NULL;
    nextNode = NULL;
    nextNodeFind = false;
    printf("\n中序遍历序列:\n");
    InOrder(bt);
    if(preNode!=NULL && nextNode==NULL) {
        printf("\n当前结点:%d,前驱结点 :%d",p->data,preNode->data);
    } else if(preNode == NULL && nextNode != NULL) {
        printf("\n当前结点:%d,后继结点 :%d",p->data,nextNode->data);
    } else if(preNode != NULL && nextNode != NULL) {
        printf("\n当前结点:%d,前驱结点:%d,后继结点:%d",p->data,preNode->data,nextNode->data);
    }



//    printf("\n当前结/点:%d\n,前驱结点:%d,后继结点:%d",t211->data,pre->data,next->data);

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值