不知不觉已经12月了,感觉离胜利的日子已经不远了,啊啊啊。
下午回宿舍解决一下没怎么写过层次遍历和孩子兄弟树的问题。
先写了个二叉树的层次遍历试试(手动赋值实在是太麻烦了)
#include <stdio.h>
typedef struct BiTNode{
char val;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
// 递归中序遍历
// 前中后 英文 preorder/inorder/postorder traversal
void InOrderTraversal(BiTree T){
if(T != NULL){
InOrderTraversal(T->lchild);
printf("%c ", T->val);
InOrderTraversal(T->rchild);
}
}
// 层次遍历
// 使用队列
void LevelOrderTraversal(BiTree T){
int BQueueLength = 100;
BiTree BQueue[100];
BiTree tmp; // 临时二叉树指针
int rear, front;
rear = 0; // 队尾
front = 0; // 队头
// 将第一个节点加入队列
BQueue[rear] = T;
rear ++;
while(rear != front){ // 判断队空
// 取队头元素
tmp = BQueue[front];
front ++;
// 将队头元素的子孙加入队列
if (tmp->lchild != NULL){
BQueue[rear] = tmp->lchild;
rear ++;
}
if (tmp->rchild != NULL){
BQueue[rear] = tmp->rchild;
rear ++;
}
printf("%c ", tmp->val);
}
}
int main(){
// 创建二叉树
BiTree T = new BiTNode;
T->val = 'A';
T->lchild = new BiTNode;
T->rchild = NULL;
T->lchild->val = 'B';
T->lchild->lchild = new BiTNode;
T->lchild->lchild->val = 'C';
T->lchild->lchild->lchild = NULL;
T->lchild->lchild->rchild = NULL;
T->lchild->rchild = new BiTNode;
T->lchild->rchild->val = 'D';
T->lchild->rchild->lchild = new BiTNode;
T->lchild->rchild->lchild->val = 'E';
T->lchild->rchild->lchild->lchild = NULL;
T->lchild->rchild->lchild->rchild = new BiTNode;
T->lchild->rchild->lchild->rchild->val = 'G';
T->lchild->rchild->lchild->rchild->rchild = NULL;
T->lchild->rchild->lchild->rchild->lchild = NULL;
T->lchild->rchild->rchild = new BiTNode;
T->lchild->rchild->rchild->val = 'F';
T->lchild->rchild->rchild->rchild = NULL;
T->lchild->rchild->rchild->lchild = NULL;
// 递归遍历测试
InOrderTraversal(T);
printf("\n--------------------\n");
// 层次遍历测试
LevelOrderTraversal(T);
return 0;
}
之后再写个孩子兄弟树的层次遍历(毕竟考的次数很多)
跟二叉树的层次遍历有点区别,是每次直接把小孩全都入队【也就是把左子树的右子树全部整进去】,中间那块儿写的还是有点乱的,把逻辑理清楚就没问题了。
代码如下:
// 对应真题2021数据结构第一题
#include <stdio.h>
typedef struct CSNode{
int val;
struct CSNode *firstchild, *nextsibling; // firstchild本质上就是左子树 nextsibling本质上就是右子树
// 因为手动创建实在是太tm麻烦了所以当成class来用了
CSNode(int val){
this->val = val;
this->firstchild = NULL;
this->nextsibling = NULL;
}
}CSNode, *CSTree;
void LevelOrderTraversal(CSTree T){
CSTree tmp; // 临时变量
CSTree tmp0;
// 初始化队列
const int queuelength = 100;
CSTree CQueue[100];
int rear = 0;
int front = 0;
// 将第一个节点入队
CQueue[rear] = T;
rear ++;
while (rear != front){
// 取队头节点
tmp = CQueue[front];
front = (front + 1) % queuelength; // 循环队列,上一个代码没写mod
// 将孩子+孩子的兄弟加入队列【这里和二叉树的层次遍历是不一样的需要注意】
if (tmp->firstchild != NULL){
CQueue[rear] = tmp->firstchild;
rear = (rear + 1)% queuelength;
tmp0 = tmp->firstchild;
while (tmp0->nextsibling != NULL){
CQueue[rear] = tmp0->nextsibling;
rear = (rear + 1) % queuelength;
tmp0 = tmp0->nextsibling;
}
}
// 输出
printf("输出:%d \n", tmp->val);
}
}
void LevelOrderTraversalAndFind(CSTree T, int val){
CSTree tmp; // 临时变量
CSTree tmp0;
CSTree parent;
// 初始化队列
const int queuelength = 100;
CSTree CQueue[100];
int rear = 0;
int front = 0;
// 将第一个节点入队
CQueue[rear] = T;
rear ++;
while (rear != front){
// 取队头节点
tmp = CQueue[front];
parent = tmp;
front = (front + 1) % queuelength; // 循环队列,上一个代码没写mod
// 将孩子+孩子的兄弟加入队列【这里和二叉树的层次遍历是不一样的需要注意】
if (tmp->firstchild != NULL){
CQueue[rear] = tmp->firstchild;
rear = (rear + 1)% queuelength;
tmp0 = tmp->firstchild;
// 看看刚入队的是不是要找的
if (tmp->firstchild->val == val){
// 找到了
printf("双亲:%d\n", parent->val);
// 遍历兄弟
tmp0 = parent->firstchild;
while (tmp0->nextsibling != NULL){
printf(" > 兄弟: %d \n", tmp0->nextsibling->val);
tmp0 = tmp0->nextsibling;
}
return;
}
while (tmp0->nextsibling != NULL){
CQueue[rear] = tmp0->nextsibling;
rear = (rear + 1) % queuelength;
// 判断是不是要找到的
if (tmp0->nextsibling->val == val){
printf("双亲:%d \n", parent->val);
tmp0 = parent->firstchild;
printf(" > 兄弟: %d \n", parent->firstchild->val);
while(tmp0->nextsibling != NULL){
printf(" > 兄弟: %d \n", tmp0->nextsibling->val);
tmp0 = tmp0->nextsibling;
}
return;
}
tmp0 = tmp0->nextsibling;
}
}
// 输出
printf("输出:%d \n", tmp->val);
}
}
int main(){
CSTree T = new CSNode(1);
T->firstchild = new CSNode(2);
T->firstchild->nextsibling = new CSNode(4);
T->firstchild->nextsibling->nextsibling = new CSNode(6);
T->firstchild->firstchild = new CSNode(3);
T->firstchild->firstchild->nextsibling = new CSNode(5);
T->firstchild->nextsibling->nextsibling->firstchild = new CSNode(7);
T->firstchild->nextsibling->nextsibling->firstchild->firstchild = new CSNode(8);
T->firstchild->nextsibling->nextsibling->firstchild->firstchild->nextsibling = new CSNode(9);
T->firstchild->nextsibling->nextsibling->firstchild->firstchild->nextsibling->nextsibling = new CSNode(10);
// 层次遍历
LevelOrderTraversal(T);
printf("\n====================================\n");
// 层次遍历找指定节点的双亲和兄弟
int val = 8;
LevelOrderTraversalAndFind(T, val);
return 0;
}
0 Comments latest
No comments.