//
// Created by Cauchyshy on 2023/5/30.
//
#include <cstdio>
#include <iostream>
#include <malloc.h>
using namespace std;
struct treeNode {
int a; // 数据成员
struct treeNode *pFather; // 父节点
struct treeNode *pLeft; // 左孩子
struct treeNode *pRight; // 右孩子
};
struct queue {
struct treeNode *tree;
struct queue *next;
};
struct treeNode* createTree(int *arr, int len) {
if (NULL == arr || len <= 0)
return NULL;
// 申请节点
struct treeNode* root = (struct treeNode*)malloc(sizeof(struct treeNode) * len);
if (NULL == root) {
return NULL;
}
// 赋初值
for (int i = 0; i < len; ++i) {
root[i].a = arr[i];
root[i].pFather = NULL;
root[i].pLeft = NULL;
root[i].pRight = NULL;
}
// 树节点连接
for (int i = 0; 2 * i + 1 < len; ++i) {
root[i].pLeft = &root[2 * i + 1]; // 左节点赋值
root[2 * i + 1].pFather = &root[i];
if (2 * i + 2 < len) {
root[i].pRight = &root[2 * i + 2]; // 右节点
root[2 * i + 2].pFather = &root[i];
}
}
// 返回树根
return root;
}
// 入队函数
void push(struct queue** queueHead, struct queue** queueTail, struct treeNode* node) {
if (node == NULL) {
return ;
}
// 申请节点
struct queue* tp = (struct queue*)malloc(sizeof(struct queue));
if (tp == NULL) {
return ;
}
// 节点赋值
tp->tree = node;
tp->next = NULL;
// 连接
// 队列为空 既是头也是尾
if (NULL == *queueHead) {
*queueHead = tp;
// *queueTail = tp;
} else {
(*queueTail)->next = tp;
// *queueTail = tp;
}
*queueTail = tp;
}
// 出队 头删
struct treeNode * pop(struct queue** queueHead, struct queue** queueTail) {
if (*queueHead == NULL || *queueTail == NULL) {
return NULL;
}
// 记录头
struct queue *tp = *queueHead;
// 头想象走一个节点
(*queueHead) = (*queueHead)->next;
// 释放刚才的节点
struct treeNode *res = tp->tree;
free(tp);
// 刚好一个节点 往下走就是空了
if (NULL == *queueHead) { // 队列放空
*queueHead = NULL;
*queueTail = NULL;
}
return res;
}
// 层序遍历
void look(struct queue** queueHead, struct queue** queueTail, struct treeNode *root) {
if (NULL == root) {
return ;
}
push(queueHead, queueTail, root); // 根入队
while (1) {
struct treeNode* tp = pop(queueHead, queueTail);
printf("%d ", tp->a);
if (tp->pLeft != NULL)
push(queueHead, queueTail, tp->pLeft);
if (tp->pRight != NULL)
push(queueHead, queueTail, tp->pRight);
if (*queueHead == NULL)
break;
}
}
// 修改指定节点
void modify(struct queue** queueHead, struct queue** queueTail, struct treeNode *root, int oldVal, int newVal) {
if (NULL == root) {
return ;
}
push(queueHead, queueTail, root); // 根入队
while (1) {
struct treeNode* tp = pop(queueHead, queueTail);
// printf("%d ", tp->a);
if (oldVal == tp->a)
tp->a = newVal; // 找到后修改
if (tp->pLeft != NULL)
push(queueHead, queueTail, tp->pLeft);
if (tp->pRight != NULL)
push(queueHead, queueTail, tp->pRight);
if (*queueHead == NULL)
break;
}
}
// 清空队列
void clearQueue(struct queue** queueHead, struct queue** queueTail) {
while (pop(queueHead, queueTail));
}
// 添加一个节点
void insert(struct queue** queueHead, struct queue** queueTail, struct treeNode **root, int data) {
if (NULL == root) {
return ;
}
// 空树, 节点即为根
if (NULL == *root) {
// 申请节点
struct treeNode *tp = (struct treeNode *) malloc(sizeof(struct treeNode));
if (NULL == tp)
return ;
// 节点成员赋值
tp->a = data;
tp->pLeft = NULL;
tp->pRight = NULL;
tp->pFather = NULL;
// 设置为树根
*root = tp;
return ;
}
push(queueHead, queueTail, *root);
while (1) {
struct treeNode *tp = pop(queueHead, queueTail);
if (NULL == tp->pLeft) {
// 添加到左子树
// 创建节点
struct treeNode *temp = (struct treeNode*)malloc(sizeof(struct treeNode));
if (NULL == temp) {
return ;
}
// 成员赋值
temp->a = data;
temp->pFather = NULL;
temp->pLeft = NULL;
temp->pRight = NULL;
// 连接
tp->pLeft = temp;
temp->pFather = tp;
// 清空队列 防止残留
clearQueue(queueHead, queueTail);
break; // return ;
}
if (NULL == tp->pRight) {
// 添加到右子树上
// 创建节点
struct treeNode *temp = (struct treeNode*)malloc(sizeof(struct treeNode));
if (NULL == temp) {
return ;
}
// 成员赋值
temp->a = data;
temp->pFather = NULL;
temp->pLeft = NULL;
temp->pRight = NULL;
// 连接
tp->pRight = temp;
temp->pFather = tp;
// 清空队列 防止残留
clearQueue(queueHead, queueTail);
break; // return ;
}
if (NULL != tp->pLeft) {
push(queueHead, queueTail, tp->pLeft);
}
if (NULL != tp->pRight) {
push(queueHead, queueTail, tp->pRight);
}
}
}
// 删除 这里不进行删除指定元素 因为会破坏完全二叉树的结构
void freeTree(int cn, struct queue** queueHead, struct queue** queueTail, struct treeNode **root) {
if (NULL == root || NULL == *root) {
return ;
}
push(queueHead, queueTail, *root);
int cnt = 0;
while (1) {
struct treeNode *tp = pop(queueHead, queueTail);
cnt++;
if (tp->pLeft != NULL)
push(queueHead, queueTail, tp->pLeft);
if (tp->pRight != NULL)
push(queueHead, queueTail, tp->pRight);
if (cnt > cn) // cnt > len 因为是个数组
free(tp);
if (NULL == *queueTail)
break;
}
// 树置为空
if (cn != 0)
free(*root);
*root = NULL;
}
// 删除最后一个节点
void deleteCreate(int cn, struct queue **head, struct queue **tail, struct treeNode** root) {
if (NULL == root || NULL == *root)
return ;
push(head, tail, *root);
struct treeNode *tp = NULL;
int pos = 0;
while (1) {
tp = pop(head, tail);
pos++;
if (tp->pLeft != NULL) {
push(head, tail, tp->pLeft);
}
if (tp->pRight != NULL) {
push(head, tail, tp->pRight);
}
if (NULL == *head)
break;
}
// 做完了之后tp就是完全二叉树的最后一个节点
if (tp->pFather == NULL) {
// tp为根
free(tp);
*root = NULL;
return ;
}
if (tp == (tp->pFather->pLeft)) {
// 为父指针的左子树
tp->pFather->pLeft = NULL;
if (pos > cn)
free(tp);
return ;
}
if (tp == (tp->pFather->pRight)) {
tp->pFather->pRight = NULL;
if (pos > cn)
free(tp);
return ;
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int cnt = 0;
cnt = sizeof(arr) / (sizeof(arr[0]));
// int arr[] = {};
// struct treeNode *root = createTree(arr, 10);
struct treeNode *root = createTree(arr, 10);
struct queue * queueHead = NULL;
struct queue * queueTail = NULL;
look(&queueHead, &queueTail, root);
printf("\n");
insert(&queueHead, &queueTail, &root, 11);
insert(&queueHead, &queueTail, &root, 12);
insert(&queueHead, &queueTail, &root, 13);
// modify(&queueHead, &queueTail, root, 2, 88); // 2改成8
// modify(&queueHead, &queueTail, root, 88, 2); // 2改成8
//
// look(&queueHead, &queueTail, root);
// printf("\n");
// 删除insert的时候加个free即可
deleteCreate(cnt, &queueHead, &queueTail, &root);
deleteCreate(cnt, &queueHead, &queueTail, &root);
deleteCreate(cnt, &queueHead, &queueTail, &root);
deleteCreate(cnt, &queueHead, &queueTail, &root);
deleteCreate(cnt, &queueHead, &queueTail, &root);
look(&queueHead, &queueTail, root);
printf("\n");
// insert 不算进cnt里面 如果不创建 cnt就是0
freeTree(cnt, &queueHead, &queueTail, &root);
return 0;
}
完全二叉树的各种操作
最新推荐文章于 2024-05-31 14:42:05 发布