目录
二叉树的数据类型定义
- 定义Elemtype为char类型, 这样以后如果数据变成int类型就不用一个个函数地去修改
typedef char Elemtype;
typedef struct node
{
Elemtype data;
struct node *lchild;
struct node *rchild;
}BTNode;
括号法创建二叉树
//初始化二叉树
void InitBiTree(BTNode *&T)
{
T=NULL;
}
//括号法创建二叉树
void CreateBiTree(BTNode *&T, char *a)
{
BTNode *St[MaxNode],*p = NULL;
int top = -1;
int tag;
int j = 0;
char ch;
InitBiTree(T); //初始化
ch = a[j];
while(ch!='\0'){
switch(ch){
case'(':
top ++;
St[top] = p;
tag = 1;
break;
case')':
top--;
break;
case',':
tag = 2;
break;
default:
p = (BTNode*) malloc (sizeof(BTNode));
p->data = ch;
p->lchild = p->rchild = NULL;
if(T == NULL)
{
T = p;
}else
{
switch(tag)
{
case 1:
St[top]->lchild=p;
break;
case 2:
St[top]->rchild=p;
break;
}
}
}
j++;
ch = a[j];
}
}
括号法输出二叉树
//输出二叉树
void PrintBiTree(BTNode *T)
{
if(T != NULL)
{
visite(T);
if(T->lchild != NULL || T->rchild != NULL)
{
printf("(");
PrintBiTree(T->lchild);
if(T->rchild != NULL)
printf(",");
PrintBiTree(T->rchild);
printf(")");
}
}
}
横向输出二叉树
//横向输出
void PrintBiTree(BTNode *T, int level){
if(T != NULL)
{
PrintBiTree(T->rchild, level+1);
if(level != 0){
for(int i = 0; i < 4 * (level-1); i++)
{
printf("%s"," ");
}
printf("%s", "---");
}
visite(T);
printf("\n");
PrintBiTree(T->lchild, level + 1);
}
}
统计二叉树节点个数
int StatNode (BTNode *T)
{
if(T==NULL)
{
return 0;
}else
return StatNode(T->lchild) + StatNode(T->rchild) + 1; //结点个数为左子树结点+右子树结点+1
}
中序遍历二叉树并输出
中序遍历: 访问左子树->根->访问右子树
前序遍历:根->访问左子树->访问右子树
后序遍历:访问左子树->访问右子树->根
//访问二叉树节点
void visite(BTNode *T)
{
if(T == NULL)
printf("该节点不存在\n");
else
printf("%2c", T->data);
}
//访问左节点
BTNode *LchildNode(BTNode *p)
{
if(p->lchild)
return p->lchild;
else
return NULL;
}
//访问右节点
BTNode *RchildNode(BTNode *p)
{
if(p->rchild)
return p->rchild;
else
return NULL;
}
//中序遍历二叉树
void MidTraverse(BTNode *T)
{
if(T != NULL)
{
MidTraverse(T->lchild);
visite(T);
MidTraverse(T->rchild);
}
}
层序遍历二叉树并输出
使用队列的先进先出的操作规律将二叉树上的节点一层一层地输出。
所以要先写队列的一些基本操作。
//队列结构体
typedef struct QueueNode {
BTNode *value; // 存储二叉树节点指针
struct QueueNode *next; // 指向下一个队列节点
} QueueNode;
//队列
typedef struct SqQueue
{
QueueNode *front; // 队首指针
QueueNode *rear; // 队尾指针
}SqQueue;
//初始化队列
void InitSqQueue(SqQueue *&Q)
{
Q = (SqQueue *) malloc (sizeof(SqQueue));
Q->front = Q->rear = NULL;
}
//队列判空
bool QueueEmpty(SqQueue *Q)
{
if (Q->front == NULL)
{
return true;
}else
{
return false;
}
}
// 释放队列的内存空间
void DestroyQueue(SqQueue *&Q)
{
free(Q);
}
//入队
void Enqueue(SqQueue *&Q, BTNode *data)
{
// 创建一个新的队列节点
QueueNode *newNode = (QueueNode *) malloc (sizeof(QueueNode));
newNode->value = data;
newNode->next = NULL;
// 如果队列为空,那么新节点就是队首和队尾
if (QueueEmpty(Q))
{
Q->front = newNode;
Q->rear = newNode;
} else
{
// 否则,把新节点插入到队尾,并更新队尾指针
Q->rear->next = newNode;
Q->rear = newNode;
}
}
// 出队
BTNode *Dequeue(SqQueue *Q) {
// 如果队列为空,返回NULL
if (QueueEmpty(Q))
{
return NULL;
}
// 否则,取出队首节点的数据,并更新队首指针
QueueNode *temp = Q->front;
BTNode *data = temp->value;
Q->front = temp->next;
// 如果出队后队列为空,那么把队尾指针也置为NULL
if (Q->front == NULL) {
Q->rear = NULL;
}
// 释放出队节点的内存空间,并返回数据
free(temp);
return data;
}
//层序遍历
void SequenceBiTree(BTNode *T)
{
if (T == NULL)
{
return;
}
SqQueue *Q; // 定义一个队列
InitSqQueue(Q);
Enqueue(Q, T);
while(!QueueEmpty(Q)) // 当队列不为空时
{
BTNode *tree = Dequeue(Q); // 取出队列第一个元素
printf("%2c", tree->data); // 输出当前结点的数据
if (tree->lchild != NULL) // 如果当前结点有左孩子
{
Enqueue(Q, tree->lchild); // 将左孩子入队
}
if (tree->rchild != NULL) // 如果当前结点有右孩子
{
Enqueue(Q, tree->rchild); // 将右孩子入队
}
}
DestroyQueue(Q);
}
判断两节点是否是兄弟节点
//判断兄弟节点
bool BrotherNode(BTNode *T, char x, char y)
{
if (T == NULL)
{
return false;
}
if (T->lchild != NULL && T->rchild != NULL)
{
if ((T->lchild->data == x && T->rchild->data == y)||(T->lchild->data == y && T->rchild->data == x))
{
return true;
}
}
return BrotherNode(T->lchild, x, y) || BrotherNode(T->rchild, x, y);
}
主函数测试
int main(){
BTNode *T;
char x = 0;
char y = 0;
InitBiTree(T);
char str[] = "(1(2,3(4(6,),5))"; //创建二叉树
CreateBiTree(T, str);
printf("该二叉树为:");
PrintBiTree(T); //输出二叉树
printf("\n");
PrintBiTree(T, 0); //横向输出二叉树
printf("%d\n", len);
printf("节点个数有:");
int node = StatNode(T); //统计二叉树节点个数
printf("%d\n", node);
printf("二叉树的中序遍历为:"); //中序遍历二叉树
MidTraverse(T);
printf("\n");
printf("二叉树的层序遍历为: ");
SequenceBiTree(T); //层序遍历二叉树
printf("\n");
printf("请输入 x 和 y:(空格分开)");
scanf("%c %c", &x, &y);
if (BrotherNode(T, x, y)) //xy否为兄弟节点
{
printf("%c 和 %c 是兄弟节点\n", x, y);
}else
{
printf("%c 和 %c 不是兄弟节点\n", x, y);
}
DestroyBiTree(T);
return 0;
}
程序运行结果
代码整合
#include<stdio.h>
#include<malloc.h>
#define MaxNode 100
typedef char Elemtype;
typedef struct node
{
Elemtype data;
struct node *lchild;
struct node *rchild;
}BTNode;
//队列结构体
typedef struct QueueNode {
BTNode *value; // 存储二叉树节点指针
struct QueueNode *next; // 指向下一个队列节点
} QueueNode;
//队列
typedef struct SqQueue
{
QueueNode *front; // 队首指针
QueueNode *rear; // 队尾指针
}SqQueue;
void InitSqQueue(SqQueue *&Q)
{
Q = (SqQueue *) malloc (sizeof(SqQueue));
Q->front = Q->rear = NULL;
}
bool QueueEmpty(SqQueue *Q)
{
if (Q->front == NULL)
{
return true;
}else
{
return false;
}
}
// 释放队列的内存空间
void DestroyQueue(SqQueue *&Q)
{
free(Q);
}
//入队
void Enqueue(SqQueue *&Q, BTNode *data)
{
// 创建一个新的队列节点
QueueNode *newNode = (QueueNode *) malloc (sizeof(QueueNode));
newNode->value = data;
newNode->next = NULL;
// 如果队列为空,那么新节点就是队首和队尾
if (QueueEmpty(Q))
{
Q->front = newNode;
Q->rear = newNode;
} else
{
// 否则,把新节点插入到队尾,并更新队尾指针
Q->rear->next = newNode;
Q->rear = newNode;
}
}
// 出队操作
BTNode *Dequeue(SqQueue *Q) {
// 如果队列为空,返回NULL
if (QueueEmpty(Q))
{
return NULL;
}
// 否则,取出队首节点的数据,并更新队首指针
QueueNode *temp = Q->front;
BTNode *data = temp->value;
Q->front = temp->next;
// 如果出队后队列为空,那么把队尾指针也置为NULL
if (Q->front == NULL) {
Q->rear = NULL;
}
// 释放出队节点的内存空间,并返回数据
free(temp);
return data;
}
//初始化二叉树
void InitBiTree(BTNode *&T)
{
T=NULL;
}
//创建二叉树
void CreateBiTree(BTNode *&T, char *a)
{
BTNode *St[MaxNode],*p = NULL;
int top = -1;
int tag;
int j = 0;
char ch;
InitBiTree(T); //初始化
ch = a[j];
while(ch!='\0'){
switch(ch){
case'(':
top++;
St[top] = p;
tag = 1;
break;
case')':
top--;
break;
case',':
tag = 2;
break;
default:
p = (BTNode*) malloc (sizeof(BTNode));
p->data = ch;
p->lchild = p->rchild = NULL;
if(T == NULL)
{
T = p;
}else
{
switch(tag)
{
case 1:
St[top]->lchild=p;
break;
case 2:
St[top]->rchild=p;
break;
}
}
}
j++;
ch = a[j];
}
}
//找到左右节点
BTNode *LchildNode(BTNode *p)
{
if(p->lchild)
return p->lchild;
else
return NULL;
}
BTNode *RchildNode(BTNode *p){
if(p->rchild)
return p->rchild;
else
return NULL;
}
//访问二叉树节点
void visite(BTNode *T)
{
if(T == NULL)
printf("该节点不存在\n");
else
printf("%2c", T->data);
}
//输出二叉树
void PrintBiTree(BTNode *T)
{
if(T != NULL)
{
visite(T);
if(T->lchild != NULL || T->rchild != NULL)
{
printf("(");
PrintBiTree(T->lchild);
if(T->rchild != NULL)
printf(",");
PrintBiTree(T->rchild);
printf(")");
}
}
}
//横向输出
void PrintBiTree(BTNode *T, int level){
if(T != NULL)
{
PrintBiTree(T->rchild, level+1);
if(level != 0){
for(int i = 0; i < 4 * (level-1); i++)
{
printf("%s"," ");
}
printf("%s", "---");
}
visite(T);
printf("\n");
PrintBiTree(T->lchild, level + 1);
}
}
//销毁二叉树
void DestroyBiTree(BTNode *&T)
{
if(T != NULL)
{
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
free(T);
}
}
//统计节点个数
int StatNode (BTNode *T)
{
if(T==NULL)
{
return 0;
}else
return StatNode(T->lchild) + StatNode(T->rchild) + 1; //结点个数为左子树结点+右子树结点+1
}
//判断兄弟节点
bool BrotherNode(BTNode *T, char x, char y)
{
if (T == NULL)
{
return false;
}
if (T->lchild != NULL && T->rchild != NULL)
{
if ((T->lchild->data == x && T->rchild->data == y)||(T->lchild->data == y && T->rchild->data == x))
{
return true;
}
}
return BrotherNode(T->lchild, x, y) || BrotherNode(T->rchild, x, y);
}
//中序遍历二叉树
void MidTraverse(BTNode *T)
{
if(T != NULL)
{
MidTraverse(T->lchild);
visite(T);
MidTraverse(T->rchild);
}
}
//层序遍历
void SequenceBiTree(BTNode *T)
{
if (T == NULL)
{
return;
}
SqQueue *Q; // 定义一个队列
InitSqQueue(Q);
Enqueue(Q, T);
while(!QueueEmpty(Q)) // 当队列不为空时
{
BTNode *tree = Dequeue(Q); // 取出队列第一个元素
printf("%2c", tree->data); // 输出当前结点的数据
if (tree->lchild != NULL) // 如果当前结点有左孩子
{
Enqueue(Q, tree->lchild); // 将左孩子入队
}
if (tree->rchild != NULL) // 如果当前结点有右孩子
{
Enqueue(Q, tree->rchild); // 将右孩子入队
}
}
DestroyQueue(Q);
}
int main(){
BTNode *T;
char x = 0;
char y = 0;
InitBiTree(T);
char str[] = "(1(2,3(4(6,),5))"; //创建二叉树
CreateBiTree(T, str);
printf("该二叉树为:");
PrintBiTree(T); //输出二叉树
printf("\n");
PrintBiTree(T, 0); //横向输出二叉树
printf("节点个数有:");
int node = StatNode(T); //统计二叉树节点个数
printf("%d\n", node);
printf("二叉树的中序遍历为:"); //中序遍历二叉树
MidTraverse(T);
printf("\n");
printf("二叉树的层序遍历为: ");
SequenceBiTree(T); //层序遍历二叉树
printf("\n");
printf("请输入 x 和 y:(空格分开)");
scanf("%c %c", &x, &y);
if (BrotherNode(T, x, y)) //xy否为兄弟节点
{
printf("%c 和 %c 是兄弟节点\n", x, y);
}else
{
printf("%c 和 %c 不是兄弟节点\n", x, y);
}
DestroyBiTree(T);
return 0;
}