#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;
}
数据结构复习:二叉树的链式存储实现
最新推荐文章于 2023-02-01 21:49:34 发布