#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ElemType char
#define ref '0' //表示为空
#define MaxSize 20
//结点结构
typedef struct BinTreeNode {
int lmax;//这俩变量用于求字数最大距离
int rmax;
int k;//第k小
int count;//储存以该节点为根的结点个数
ElemType data;
struct BinTreeNode* leftChild;
struct BinTreeNode* rightChild;
}BinTreeNode;
//根节点管理
typedef struct BinTree {
BinTreeNode* root;
}BinTree;
/*链式队列结点*/
typedef struct LinkNode {
BinTreeNode* data;
struct LinkNode* next;
}LinkNode;
/*链式队列*/
typedef struct LinkQueue {
LinkNode* front, * rear;//队列的对头和队尾指针
}LinkQueue;
typedef struct StackNode { //先,中序非递归栈的链式存储
BinTreeNode* data;
struct StackNode* next;
}LinkStack, StackNode;
typedef enum {
L, //左
R //右
}Tag;
typedef struct StkNode {
BinTreeNode* data; //保存结点地址
Tag tag; //标记(标记左还是右)
struct StkNode* next;
}StkNode;
typedef struct SeqStack { //后序非递归栈的链式存储
StkNode* data;
struct StkNode* next;
}SeqStack;
typedef struct
{
BinTreeNode* data[MaxSize];
int isFirst[MaxSize];
int top;
}Stack;
int count = 0; //用于统计二叉树叶子节点个数
int count1 = 0;
int count_1 = 0;
int len = 0; //字数最大距离
int zero = 0,one = 0,two = 0;
int predt = -32767;
static LinkNode* list=NULL;
static LinkNode* list1=NULL;
void InitBinTree(BinTree* bt); //二叉树的初始化
BinTreeNode* CreateBinTree(); //二叉树的创建 通过返回值返回二叉树
void CreateBinTree_2(BinTree* tree, BinTreeNode** node); //二叉树的创建 使用二级指针
int Size(BinTreeNode* tree); //统计结点个数
int Height(BinTreeNode* tree); //统计二叉树高度 (递归)
int Heigth_1(BinTreeNode* tree); //统计二叉树高度(非递归)
BinTreeNode* Search(BinTreeNode* tree,ElemType e); //查找某个结点
BinTreeNode* Parent(BinTreeNode* tree,BinTreeNode* p); //查找父节点
void LeafNumber(BinTreeNode* tree); //统计叶子节点个数
BinTreeNode* lowestCommonAncestor(BinTreeNode* root,BinTreeNode* p,BinTreeNode* q);//找最近祖先
int count_node(BinTreeNode *root);//统计二叉树结点个数
/*递归方式*/
void PreOrder(BinTreeNode* t); //先序遍历
void InOrder(BinTreeNode* t); //中序遍历
void PostOrder(BinTreeNode* t); //后序遍历
/*非递归方式*/
void LevelOrder(BinTreeNode* t); //层序遍历
void PreOrder_1(BinTreeNode* t); //先序遍历
void InOrder_1(BinTreeNode* t); //中序
void PostOrder_1(BinTreeNode* t); //非递归后序遍历
void InitQueue(LinkQueue* Q);
void EnQueue(LinkQueue* Q, BinTreeNode* e);
void DeQueue(LinkQueue* Q);
void getHead(LinkQueue* Q, BinTreeNode* e);
int IsEmptyQ(LinkQueue* Q);
void InitStack_2(LinkStack* s);//非递归先序,中序栈的链式存储
void Push_2(LinkStack* s, BinTreeNode* e);
int IsEmpty_2(LinkStack* s);
void Pop_2(LinkStack* s, BinTreeNode* e);
void InitStack(SeqStack* s);//非递归后序,栈的链式存储
void Push(SeqStack* s, StkNode e);
int IsEmpty(SeqStack* s);
void Pop(SeqStack* s, StkNode* e);
//143
//03
void PostOrder_2(BinTreeNode* t); //非递归后序遍历
//04
void LevelOrder2(BinTreeNode* t);
//05
int Heigth_1(BinTreeNode* tree); //统计二叉树高度(非递归)
//06
BinTreeNode* PreInCreate(ElemType A[],ElemType B[],int pre1,int pre2,int in1,int in2);
//07
int isPerfectTree(BinTreeNode* t);
//08
int countDoubleNode(BinTreeNode* t);
//09
void swap(BinTreeNode* t);
ElemType findK(BinTreeNode* t,int k);
void deleteXTree(BinTreeNode* t);
//11
void deleteX(BinTreeNode* t,char x);
//12
int printXAllParent(BinTreeNode* t,char x); //打印值为x的所有祖先
//14
int Width(BinTreeNode* t);
//15
void PreToPost(ElemType Pre[],int l1,int h1,ElemType Post[],int l2,int h2);
int WwightPathLength(BinTreeNode* t,int len);
void Find_two_child(BinTreeNode* t);
void BtreeTozExp(BinTreeNode* t,int deep);//deep表示深度,默认为1
void Listleaf(BinTreeNode* t);
Stack getPath(BinTreeNode* t,char x); //找根节点t到值为x节点的路径
void PreOrder_3(BinTreeNode* t,int level,int width[]);
int treeWidth(BinTreeNode* t);
int FindMaxLen(BinTreeNode* t);
int level_x(BinTreeNode* t,char x);//查找值为x所在的层树
BinTreeNode* Ancestor(BinTreeNode* t,BinTreeNode* p,BinTreeNode* q);
void count_zero_one_tow(BinTreeNode* t);
void count_zero_one_tow_1(BinTreeNode* t);
int is_Symmetry(BinTreeNode* t);
int is_Symmetry_helper(BinTreeNode* left,BinTreeNode* right);
int minDepth(BinTreeNode* t);
BinTreeNode* mergeTrees(BinTreeNode* t1,BinTreeNode* t2);
int diameterOfBinaryTree(BinTreeNode* t);
int depth(BinTreeNode* t);
BinTreeNode* pruneTree(BinTreeNode* t);
int findTilt(BinTreeNode* t);
int treesum(BinTreeNode* t);
int isBalance(BinTreeNode* t);
int height(BinTreeNode* t);
void outPut(BinTreeNode* t,char k);
int max(int a,int b){
if(a > b)return a;
else return b;
}
int similar(BinTreeNode* t1,BinTreeNode* t2);
int JudgeBST(BinTreeNode* t);
BinTreeNode* Search_Small(BinTreeNode* t,int k);
void count_k_yezi(BinTreeNode* t,int k);
int LeafKLevel(BinTreeNode* t,int k);
void PreOrderll(BinTreeNode* t,int deep,int k);
void searchParent(BinTreeNode* t,char x);
int main() {
BinTree tree,tree1;
InitBinTree(&tree);
tree.root = CreateBinTree();
// CreateBinTree_2(&tree,&(tree.root));
// ElemType Pre[10]={'1','2','3','4','5','6','7'},Post[10];
// printf("满二叉树先序转后序:");
// PreToPost(Pre,0,6,Post,0,6);
// int i;
// for(i = 0; i <= 6; i++)printf("%c ",Post[i]);
// printf("最大宽度:%d",Width(tree.root));
// printf("x的所有根:");
// printXAllParent(tree.root,'5');
// char A[9] = {'c','1','2','4','8','5','3','6','7'},B[9] = {'c','8','4','2','5','1','6','3','7'};
// BinTreeNode* root = PreInCreate(A,B,1,8,1,8);
// printf("%c",root->data);
// printf("先序遍历:");
// PreOrder(root);
// printf("\n");
// printf("中序遍历:");
// InOrder(root);
// deleteX(tree.root,'5');
// printf("双分支结点个数: %d",countDoubleNode(tree.root));
// swap(tree.root);
printf("先序遍历:");
PreOrder(tree.root);
printf("\n");
printf("中序遍历:");
InOrder(tree.root);
printf("\n");
printf("后序遍历:");
PostOrder(tree.root);
// printf("\n");
// printf("层序遍历:");
// LevelOrder(tree.root);
// printf("\n非递归后序遍历:");
// PostOrder_2(tree.root);
// printf("\n");
// printf("非递归先序遍历:");
// PreOrder_1(tree.root);
// printf("\n");
// printf("非递归中序遍历:");
// InOrder_1(tree.root);
// printf("\n");
// printf("非递归后序遍历:");
// PostOrder_1(tree.root);
// printf("\n");
// printf("二叉树个数:%d",Size(tree.root));
printf("\n");
// printf("二叉树高度(递归):%d\n",Height(tree.root));
// printf("二叉树高度(非递归):%d",Heigth_1(tree.root));
// printf("\n");
// printf("查找结点:%c",Search(tree.root,'3')->data);
// printf("\n");
// printf("查找父结点:%c",Parent(tree.root,tree.root->leftChild->leftChild)->data);
printf("\n");
// LeafNumber(tree.root);
// printf("统计叶子结点个数:%d",count);
// printf("\n04:");
// LevelOrder2(tree.root);
//
// printf("\n");
// Find_two_child(tree.root);
// printf("俩孩子结点个数:%d",count_1);
// BtreeTozExp(tree.root,1);
// printf("\n");
// Stack s = getPath(tree.root,'9');
// while(s.top != -1){
// printf("%c ",(s.data[s.top--])->data);
// }
// Listleaf(tree.root);
// searchParent(tree.root,'9');
// while(list1 != NULL){
// printf("%c ",list1->data);
// list1 = list1->next;
// }
// printf("最大宽度:%d",treeWidth(tree.root));
// printf("俩子树最大距离:%d",FindMaxLen(tree.root));
// level_x(tree.root,'7');
// count_zero_one_tow(tree.root);
//count_zero_one_tow_1(tree.root);
// printf("zero: %d one : %d two: %d",zero,one,two);
// if(is_Symmetry(tree.root))printf("对称");
// else printf("不对称");
// printf("最小高度 :%d",minDepth(tree.root));
// InitBinTree(&tree1);
// tree1.root = CreateBinTree();
// mergeTrees(tree.root,tree1.root);
// printf("\n先序遍历:");
// PreOrder(tree1.root);
// printf("最长路径:%d",diameterOfBinaryTree(tree.root));
// tree.root = pruneTree(tree.root);
// printf("\n先序遍历:");
// PreOrder(tree.root);
// LeafKLevel(tree.root,3);
count_k_yezi(tree.root,3);
// printf("第2层叶子节点数:%d",count);
printf("第2层叶子节点数:%d",count);
// outPut(tree.root,'4');
return 0;
}
//二叉树初始化
void InitBinTree(BinTree* bt)
{
bt->root = NULL;//根设置为空
}
BinTreeNode* CreateBinTree() {
ElemType e;
scanf("%c", &e);
if (e == ref)return NULL;
BinTreeNode* node = (BinTreeNode*)malloc(sizeof(BinTreeNode));
node->data = e;
node->leftChild = CreateBinTree();
node->rightChild = CreateBinTree();
return node;
}
void CreateBinTree_2(BinTree* tree, BinTreeNode** node) {
ElemType e;
scanf("%c", &e);
if (e == ref) {
(*node) = NULL;
}
else {
(*node) = (BinTreeNode*)malloc(sizeof(BinTreeNode));
(*node)->data = e;
CreateBinTree_2(tree, &((*node)->leftChild));
CreateBinTree_2(tree, &((*node)->rightChild));
}
}
void PreOrder(BinTreeNode* t) {
if (t != NULL) {
printf("%c ", t->data);
PreOrder(t->leftChild);
PreOrder(t->rightChild);
}
}
void InOrder(BinTreeNode* t) {
if (t != NULL) {
InOrder(t->leftChild);
printf("%c ", t->data);
InOrder(t->rightChild);
}
}
void PostOrder(BinTreeNode* t) {
if (t != NULL) {
PostOrder(t->leftChild);
PostOrder(t->rightChild);
printf("%c ", t->data);
}
}
void InitQueue(LinkQueue* Q) {
LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode));
Q->front = Q->rear = p;
Q->front->next = NULL;
}
void EnQueue(LinkQueue* Q, BinTreeNode* e) {
LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode));
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
}
void getHead(LinkQueue* Q, BinTreeNode* e) {
LinkNode* p;
if (Q->front == Q->rear)return;
p = Q->front->next;
*e = *(p->data);
}
void DeQueue(LinkQueue* Q) {
LinkNode* p;
if (Q->front == Q->rear)return;
p = Q->front->next; //第一个有效结点
Q->front->next = p->next;
if (Q->rear == p) {
Q->rear = Q->front; //不能更换赋值顺序
}
free(p);
}
int IsEmptyQ(LinkQueue* Q) {
if (Q->front == Q->rear)return 1;
else return 0;
}
void LevelOrder(BinTreeNode* t) { //非递归层序遍历
if (t == NULL)return;
LinkQueue Q;
BinTreeNode node;
InitQueue(&Q);
EnQueue(&Q, t);
while (!IsEmptyQ(&Q)) {
getHead(&Q, &node);
DeQueue(&Q);
printf("%c ", node.data);
if (node.leftChild != NULL) {
EnQueue(&Q, node.leftChild);
}
if (node.rightChild != NULL) {
EnQueue(&Q, node.rightChild);
}
}
}
void InitStack_2(LinkStack* s) {
s = (StackNode*)malloc(sizeof(struct StackNode));
s->next = NULL;
}
void Push_2(LinkStack* s, BinTreeNode* e) {
StackNode* p = (StackNode*)malloc(sizeof(struct StackNode));
p->data = e;
p->next = s->next;
s->next = p;
}
int IsEmpty_2(LinkStack* s) {
return (s->next == NULL);
}
void Pop_2(LinkStack* s, BinTreeNode* e) {
if (IsEmpty_2(s))return;
StackNode* p;
p = s->next;
*e = *(p->data);
s->next = p->next;
free(p);
}
void PreOrder_1(BinTreeNode* t) {//非递归先序
if (t == NULL)return;
LinkStack* s;
BinTreeNode e;
InitStack_2(&s);
Push_2(&s, t);
while (!IsEmpty_2(&s)) {
Pop_2(&s, &e);
printf("%c ", e.data);
//栈的特点后入先出这里右孩子先入栈
if (e.rightChild != NULL) {
Push_2(&s, e.rightChild);
}
if (e.leftChild != NULL) {
Push_2(&s, e.leftChild);
}
}
}
void InOrder_1(BinTreeNode* t) {//非递归中序遍历
if (t == NULL)return;
LinkStack* s;
BinTreeNode e;
InitStack_2(&s);
Push_2(&s, t);
while (!IsEmpty_2(&s)) {
while (t != NULL && t->leftChild != NULL) {
Push_2(&s, t->leftChild);
t = t->leftChild;
}
Pop_2(&s, &e);
printf("%c ", e.data);
if (e.rightChild != NULL) {
Push_2(&s, e.rightChild);
}
}
}
void InitStack(SeqStack* s) {
s = (StkNode*)malloc(sizeof(struct StkNode));
s->next = NULL;
}
void Push(SeqStack* s, StkNode e) {
StkNode* p = (StkNode*)malloc(sizeof(struct StkNode));
*p = e;
p->next = s->next;
s->next = p;
}
int IsEmpty(SeqStack* s) {
return (s->next == NULL);
}
void Pop(SeqStack* s, StkNode* e) {
if (IsEmpty(s))return;
StkNode* p;
p = s->next;
*e = *p;
s->next = p->next;
free(p);
}
void PostOrder_1(BinTreeNode* t) { //非递归后序遍历
if (t == NULL)return;
SeqStack s;
StkNode sn;
BinTreeNode* e;
InitStack(&s);
do { //循环将树根结点一直将左边的孩子入队
while (t != NULL) {
sn.data = t;
sn.tag = L; //标记为左
Push(&s, sn);
t = t->leftChild; //查询左孩子若有就一直入队
}
int flag = 1;//判断是否循环
while (flag && !IsEmpty(&s)) {
Pop(&s, &sn);
e = sn.data; //获取树结点
switch (sn.tag) {
case L: //左标记接下来还要访问右子树此时根节点不能访问重新入队
sn.tag = R; //将左标记改为右 ,再次遇到便可输出
Push(&s, sn);
flag = 0; //停止循环让右孩子入队
t = e->rightChild; //接下来访问右孩子
break;
case R:
printf("%c ", (sn.data)->data); //右标记表示左右孩子都已输出便可输出该根节点
break;
}
}
} while (!IsEmpty(&s));
}
void PostOrder_2(BinTreeNode* t){ //非递归后序遍历
SeqStack s;
StkNode sn;
InitStack(&s);
BinTreeNode* p = t, * r = NULL;//r表示当前结点的前一个结点
while (p || !IsEmpty(&s)) {
if (p) {
sn.data = p;
Push(&s, sn);//自己写题栈存储结点设为BinTreeNode*好写
p = p->leftChild;//左子树一直入栈
}else {//左子树全入栈了
Pop(&s, &sn);
p = sn.data;
if (p->rightChild && p->rightChild != r) {//右子树非空且未访问过右子树
Push(&s,sn);//重新入栈
p = p->rightChild;//右子树接着入栈
}//右子树为空或者右子树已经访问
else {
printf("%c ", p->data);
r = p;//记录最新访问节点
p = NULL;//访问完后置为空
}
}
}
}
int Size(BinTreeNode* tree) {//二叉树结点个数
if(tree == NULL)return 0;
//二叉树个数为左子树个数+右子树个数+自己 (1)
return Size(tree->leftChild)+Size(tree->rightChild)+1;
}
int Height(BinTreeNode* tree){//二叉树高度
if(tree == NULL)return 0;
int L_Height = Height(tree->leftChild);
int R_Height = Height(tree->rightChild);
//二叉树高度为左子树与右子树最大高度加1
return (L_Height > R_Height ? L_Height : R_Height) + 1;
}
int Heigth_1(BinTreeNode* tree){ //非递归求二叉树高度
if(tree == NULL)return 0;
int front = -1,rear = -1;//分别表示队头和队尾
int last = 0,height = 0;//分别表示是否为该行最后一个结点和树高度
BinTreeNode* Q[MaxSize],*p;//Q队列
Q[++rear] = tree;//根节点入队
while(front < rear){
p = Q[++front];
if(p->leftChild){
Q[++rear] = p->leftChild;
}
if(p->rightChild){
Q[++rear] = p->rightChild;
}
if(front == last){
height++;
last = rear;
}
}
return height;
}
int level_x(BinTreeNode* tree,char x){ //查找值为x所在层次
if(tree == NULL)return 0;
int front = -1,rear = -1;//分别表示队头和队尾
int last = 0,height = 0;//分别表示是否为该行最后一个结点和树高度
BinTreeNode* Q[MaxSize],*p;//Q队列
Q[++rear] = tree;
while(front < rear){
p = Q[++front];
if(p->leftChild){
Q[++rear] = p->leftChild;
}
if(p->rightChild){
Q[++rear] = p->rightChild;
}
if(front == last){
height++;
last = rear;
}
if(p->data == x)printf("%d",height);
}
return height;
}
//判断是否是完全二叉树
int isPerfectTree(BinTreeNode* t){
if(!t)return 1;
int front = -1,rear = -1;
BinTreeNode* Q[MaxSize],*p;
Q[++rear] = t;
while(front < rear){
p = Q[++front];
if(p){
Q[++rear] = p->leftChild;
Q[++rear] = p->rightChild;
}else{//结点为空
while(front < rear){
p = Q[++front];
if(p)return 0;//有非空结点就不是完全二叉树
}
}
}
return 1;
}
typedef struct{
BinTreeNode* data[MaxSize];
int level[MaxSize];
int front,rear;
}Qu;
int Width(BinTreeNode* t){ //求二叉树最大宽度
Qu Q;
int k,max,i,n;
BinTreeNode* p;
Q.front = Q.rear = -1;
Q.rear++;
Q.data[Q.rear] = t;
Q.level[Q.rear] = 1;//初始根节点为第一层
while(Q.front < Q.rear){
Q.front++;
p = Q.data[Q.front];
k = Q.level[Q.front];
if(p->leftChild){//左子树非空左子树入队列并其所在为层次为原层次加1
Q.rear++;
Q.data[Q.rear] = p->leftChild;
Q.level[Q.rear] = k+1;
}
if(p->rightChild){
Q.rear++;
Q.data[Q.rear] = p->rightChild;
Q.level[Q.rear] = k+1;
}
}
i = 0;
k = 1;
max = 0;
while(i <= Q.rear){
n = 0;//表示同一层结点个数
while(i<=Q.rear && Q.level[i] == k){//循环统计Q.level[i]的层是为k的结点个数
i++;
n++;
}
k = Q.level[i];//退出循环时i指向下一层,此时更新要统计该层的层数
if(n > max)max = n;//更新最大宽度
}
return max;
}
void PreOrder_3(BinTreeNode* t,int level,int width[]){//与 treeWidth结合求二叉树宽度
if(t == NULL)return ;
width[level]++;
PreOrder_3(t->leftChild,level+1,width);
PreOrder_3(t->rightChild,level+1,width);
}
int treeWidth(BinTreeNode* t){
int width[MaxSize],i;
for(i = 0; i < MaxSize; i++){
width[i] = 0;//初始化
}
PreOrder_3(t,0,width);
int MaxWidth = 0;
for(i = 0; i < MaxSize; i++){
if(width[i] > MaxWidth)MaxWidth = width[i];
}
return MaxWidth;
}
Stack getPath(BinTreeNode* t,char x){ //获取从值为x结点到根节点的路径
Stack s;
s.top = -1;
while(t || s.top != -1){
while(t){
s.data[++s.top] = t;//存入栈
s.isFirst[s.top] = 1;//第一次访问
if(t->data == x)return s; //找到结点返回栈
t = t->leftChild;
}
if(s.top != -1){
BinTreeNode* p = s.data[s.top--]; //出栈
int first = s.isFirst[s.top+1];
t = p->rightChild; //如果第一次访问该节点(即还有右子树没有查找),出栈后取其右孩子后,更改访问状态再放回
if(first == 1){ //遇到0表示其不为路径不用再进栈
s.isFirst[s.top+1] = 0;
s.data[++s.top] = p;
}
}
}
return s;
}
BinTreeNode* Search(BinTreeNode* tree,ElemType key){ //查找某的结点
if(tree == NULL)return NULL;
if(tree->data == key)return tree;
BinTreeNode* p = Search(tree->leftChild,key);
if(p != NULL)return p;
return Search(tree->rightChild,key);
}
BinTreeNode* Parent(BinTreeNode* tree,BinTreeNode* p){ //查找结点p的根节点
if(tree == NULL || p == NULL){
return NULL;
}
if(tree->leftChild == p || tree->rightChild == p){
return tree;
}
BinTreeNode* q = Parent(tree->leftChild,p);
if(q != NULL){
return q;
}
return Parent(tree->rightChild,p);
}
void LeafNumber(BinTreeNode* tree){//叶结点个数
if(tree != NULL){
if(tree->leftChild == NULL && tree->rightChild == NULL)count++;
LeafNumber(tree->leftChild);
LeafNumber(tree->rightChild);
}
}
void LevelOrder2(BinTreeNode* t){//二叉树自下而上,自右向左
if(t){
SeqStack s;
StkNode sn;
InitStack(&s);
LinkQueue q;
BinTreeNode node;
InitQueue(&q);
EnQueue(&q, t);
BinTreeNode* t;
while(!IsEmptyQ(&q)){
getHead(&q, &node);
DeQueue(&q);
sn.data = &node;
Push(&s,sn);
if(node.leftChild != NULL){
EnQueue(&q, node.leftChild);
}
if(node.rightChild != NULL){
EnQueue(&q, node.rightChild);
}
}
while(!IsEmpty(&s)){
Pop(&s,&sn);
printf("%c ",sn.data->data);
}
}
}
//A数组存先序遍历结果,B存储中序遍历序列 ,进行创建二叉树
BinTreeNode* PreInCreate(ElemType A[],ElemType B[],int pre1,int pre2,int in1,int in2){
// pre1,pre2分别是先序结点的第一个下标和最后一个结点下标 pre1=1,pre2=n
// in1,in2分别是中序结点第一个下标和最后一个结点下表 in1=1,in2=n
BinTreeNode* root = (BinTreeNode*)malloc(sizeof(struct BinTreeNode));
root->data = A[pre1]; //根节点
int i,llen,rlen;
for(i = in1; B[i] != root->data; i++);//根结点在中序结点的划分
llen = i-in1; //左子树长度
rlen = in2-i; //右子树长度
if(llen){ //建立左子树
root->leftChild = PreInCreate(A,B,pre1+1,pre1+llen,in1,in1+llen-1);
}else{
root->leftChild = NULL;
}
if(rlen){ //建立右子树
root->rightChild = PreInCreate(A,B,pre2-rlen+1,pre2,in2-rlen+1,in2);
}else{
root->rightChild = NULL;
}
return root;
}
int countDoubleNode(BinTreeNode* t){ //拥有俩孩子结点个数
if(!t){
return 0;
}else if(t->leftChild != NULL && t->rightChild != NULL){
return countDoubleNode(t->leftChild)+countDoubleNode(t->rightChild)+1;
}else{
return countDoubleNode(t->leftChild)+countDoubleNode(t->rightChild);
}
}
void Find_two_child(BinTreeNode* t){ //拥有俩孩子结点个数
if(t != NULL){
Find_two_child(t->leftChild);
Find_two_child(t->rightChild);
if(t->leftChild && t->rightChild)count_1++;
}
}
/*
void count__node(BinTreeNode* t){ //求二叉树结点个数
if(t != NULL){
Find_two_child(t->leftChild);
Find_two_child(t->rightChild);
count++;
}
}
*/
void swap(BinTreeNode* t){//交换所有子树
if(t){
BinTreeNode* p;
p = t->leftChild;
t->leftChild = t->rightChild;
t->rightChild = p;
swap(t->leftChild);
swap(t->rightChild);
}
}
ElemType findK(BinTreeNode* t,int k){//找k
char ch;
if(t == NULL)return '#';
if(count1 == k)return t->data;
count1++;
ch = findK(t->leftChild,k);
if(ch != '#'){
return ch;
}
ch = findK(t->rightChild,k);
return ch;
}
void deleteXTree(BinTreeNode* t){
if(t){//后序遍历依次删除以 x为根节点的孩子
deleteXTree(t->leftChild);
deleteXTree(t->rightChild);
free(t);
}
}
void deleteX(BinTreeNode* t,char x){//删除值为x以及以他为根的子树
if(t){
if(t->data == x){
deleteXTree(t);
exit(0);
}
BinTreeNode* Q[MaxSize],*p;
int front = -1,rear = -1;
Q[++rear] = t;
while(front < rear){//层序遍历找到x结点并删除
p = Q[++front];
if(p->leftChild){
if(p->leftChild->data == x){
deleteXTree(p->leftChild);
p->leftChild = NULL;
}else{
Q[++rear] = p->leftChild;
}
}
if(p->rightChild){
if(p->rightChild->data == x){
deleteXTree(p->rightChild);
p->rightChild = NULL;
}else{
Q[++rear] = p->rightChild;
}
}
}
}
}
int printXAllParent(BinTreeNode* t,char x){//输出值为x的所有祖先,
int key1 = 0,key2 = 0;
if(t == NULL)return 0;
if(t->data != x){
key1 = printXAllParent(t->leftChild,x);
key2 = printXAllParent(t->rightChild,x);
}else if(t->data == x){
return 1;
}
if(key1 == 1){
printf("%c ",t->data);
return 1;
}
if(key2 == 1){
printf("%c ",t->data);
return 1;
}
return 0;
}
typedef struct{
BinTreeNode* t;
int tag; //0表示左孩子被访问,1表示右孩子被访问
}Stack1;
void searchParent(BinTreeNode* t,char x){//输出值为x的所有祖先,用非递归后序遍历
Stack1 s[100];//栈
int top = 0;//栈空
while(t || top > 0){
while(t && t->data != x){ //不是x一直入队
s[++top].t = t;
s[top].tag = 0;
t = t->leftChild;
}
if(t && t->data == x){ //找到x此时栈中为所有祖先
int i;
for(i = 1; i <= top; i++){
printf("%c ",s[i].t->data);
}
exit(0);
}
while(top != 0 && s[top].tag == 1){//弹出栈
top--;
}
if(top != 0){
s[top].tag = 1;
t = s[top].t->rightChild;//沿右分支向下遍历
}
}
}
BinTreeNode* Ancestor(BinTreeNode* t,BinTreeNode* p,BinTreeNode* q){//利用非递归后序遍历获得p,q最近公共结点
Stack1 s[100],s1[100];//
int top = 0;//栈空
int top1;
while(t || top > 0){
while(t){
s[++top].t = t;
s[top].tag = 0;
t = t->leftChild;
}
while(top != 0 && s[top].tag == 1){//弹出栈
//假设p在q的左侧,遇到p时栈中的元素均为p的祖先
if(s[top].t == p){
int i;
for(i = 1; i <= top; i++){
s1[i] = s[i];//复制到s1中
}
top1 = top;
}
if(s[top].t == q){//依次比较s1,s中元素第一个相等的就是最经公共祖先
int i,j;
for(i = top; i > 0; i--){
for(j = top1; j > 0; j--){
if(s1[top1].t == s[top].t)return s[top1].t;
}
}
}
top--;
}
if(top != 0){
s[top].tag = 1;
t = s[top].t->rightChild;//沿右分支向下遍历
}
}
return NULL;//没有公共结点
}
//找最近祖先
BinTreeNode* lowestCommonAncestor(BinTreeNode* root,BinTreeNode* p,BinTreeNode* q){
if(!root || !p || !q){ //有一个结点为空就不会存在公共祖先
return NULL;
}
/*
若某一个相等则root就为祖先,这俩结点在同一侧,且其中一个结点就是公共祖先
*/
if(root == p || root == q){
return root;
}
BinTreeNode* l = lowestCommonAncestor(root->leftChild,p,q);
BinTreeNode* r = lowestCommonAncestor(root->rightChild,p,q);
if(l && r){//说明这俩节点均在root的两侧
return root;
}
return l ? l : r;//说明俩节点在同一侧要么l或r为根
}
int count_node(BinTreeNode *root){//统计结点个数
if(root != NULL){
count_node(root->leftChild);
count_node(root->rightChild);
count++;
}
return count;
}
//Pre数组存先序遍历求后序
void PreToPost(ElemType Pre[],int l1,int h1,ElemType Post[],int l2,int h2){
int half; //l1先序起始位置,h1末尾 l2,h2同理
if(l1 <= h1){
Post[h2] = Pre[l1];//根据满二叉树先序遍历第一个结点等于后序遍历最后一个结点进行递归
half = (h1-l1)/2;
if((h1-l1)%2)half++;
PreToPost(Pre,l1+1,h1-half,Post,l2,l2+half-1);//转化左子树
PreToPost(Pre,l1+half+1,h1,Post,l2+half,h2-1);//转换右子树
}
}
//哈夫曼树带权路径长度
int WwightPathLength(BinTreeNode* t,int len){//len表示层树 树只有一个结点就0层
if(!t){
return;
}else{
if(t->leftChild == NULL && t->rightChild == NULL){
return t->data * len;
}else{
return WwightPathLength(t->leftChild,len + 1) + WwightPathLength(t->rightChild,len + 1);
}
}
}
void BtreeTozExp(BinTreeNode* t,int deep){//输出二叉树等价中缀表达式
if(t == NULL)return ;
if(t->leftChild == NULL && t->rightChild == NULL){
printf("%c",t->data);//表示为叶节点输出操作数
}else{
if(deep > 1)printf("("); //若有子表达式加一层括号
BtreeTozExp(t->leftChild,deep+1);
printf("%c",t->data);//输出操作符
BtreeTozExp(t->rightChild,deep+1);
if(deep > 1)printf(")");
}
}
void Listleaf(BinTreeNode* t){//将所有二叉树叶子节点存在单链表中 中序遍历找叶节点
if(t == NULL)return ;
Listleaf(t->leftChild);
if(t->leftChild == NULL && t->rightChild == NULL){
if(list == NULL){
list = t; //第一个结点作为头
list1= list; //保存头节点地址
}else{
list->next = t; //尾插
list = t;
}
}
Listleaf(t->rightChild);
}
/*
若俩结点经过根节点,则最大距离为左子树深度与右子树深度之和
若俩节点不经过根节点,则最大距离为左子树与右子树距离的最大值
*/
int FindMaxLen(BinTreeNode* t){ //求叶子节点最大距离(节点之间的边数)
if(t == NULL)return;
if(t->leftChild == NULL){
t->lmax = 0;
}
if(t->rightChild == NULL){
t->rmax = 0;
}
if(t->leftChild != NULL){
FindMaxLen(t->leftChild);
}
if(t->rightChild != NULL){
FindMaxLen(t->rightChild);
}
if(t->leftChild != NULL){
t->lmax = t->leftChild->lmax > t->leftChild->rmax ? t->leftChild->lmax+1 : t->leftChild->rmax+1;
}
if(t->rightChild != NULL){
t->rmax = t->rightChild->lmax > t->rightChild->rmax ? t->rightChild->lmax+1 : t->rightChild->rmax+1;
}
if((t->lmax + t->rmax) > len)len = t->lmax + t->rmax;
return len;
}
void count_zero_one_two(BinTreeNode* t){//非递归统计0,1,2结点个数
int zero = 0,one = 0,two = 0,top = -1,degree = 0;
BinTreeNode* s[100],*p;
if(t == NULL)return;
s[++top] = t;
while(top >= 0){
p = s[top--];
if(p->leftChild != NULL){
s[++top] = p->leftChild;
degree++;
}
if(p->rightChild != NULL){
s[++top] = p->rightChild;
degree++;
}
if(degree == 0)zero++;
if(degree == 1)one++;
if(degree == 2)two++;
degree = 0;
}
printf("zero: %d one : %d two: %d",zero,one,two);
}
void count_zero_one_tow_1(BinTreeNode* t){//递归统计,0,1,2结点个数
if(t == NULL)return;
if(t->leftChild == NULL && t->rightChild == NULL)zero++;
if(t->leftChild == NULL && t->rightChild != NULL || t->leftChild != NULL && t->rightChild == NULL)one++;
if(t->leftChild != NULL && t->rightChild != NULL)two++;
count_zero_one_tow_1(t->leftChild);
count_zero_one_tow_1(t->rightChild);
}
int is_Symmetry(BinTreeNode* t){ //判断是否是对称二叉树
if(t == NULL)return 1; //1表示对称,0表示不对称
return is_Symmetry_helper(t->leftChild,t->rightChild);
}
int is_Symmetry_helper(BinTreeNode* left,BinTreeNode* right){
if(left == NULL && right == NULL)return 1;
if(left == NULL || right == NULL)return 0;
if(left->data != right->data)return 0;
return is_Symmetry_helper(left->leftChild,right->rightChild) && is_Symmetry_helper(left->rightChild,right->leftChild);
}
int similar(BinTreeNode* t1,BinTreeNode* t2){ //判断t1与t2是否相似
if(t1 == NULL && t2 == NULL)return 1;
else if(t1 == NULL || t2 == NULL)return 0;
int l = similar(t1->leftChild,t2->leftChild);
int r = similar(t2->rightChild,t2->rightChild);
return l && r;
}
int minDepth(BinTreeNode* t){ //最小深度,从根节点到叶子节点路径上最少结点个数包括跟
if(t == NULL)return 0;
if(t->leftChild == NULL)return 1 + minDepth(t->rightChild);
if(t->rightChild == NULL)return 1 + minDepth(t->leftChild);
int llength = minDepth(t->leftChild);
int rlength = minDepth(t->rightChild);
return 1 + llength < rlength ? llength : rlength;
}
BinTreeNode* mergeTrees(BinTreeNode* t1,BinTreeNode* t2){//合并俩二叉树,对应位置相加,若t1某位置为空t2对应位置充提
if(t1 == NULL || t2 == NULL){
return t1 == NULL ? t2 : t1;
}
t1->data+=t2->data;
t1->leftChild = mergeTrees(t1->leftChild,t2->leftChild);
t1->rightChild = mergeTrees(t1->rightChild,t2->rightChild);
return t1;
}
int diameterOfBinaryTree(BinTreeNode* t){//求二叉树最长路径 (叶子节点之间最长边个数)
if(t == NULL)return 0;
int res = depth(t->leftChild) + depth(t->rightChild);//若俩孩子都有的情况
return max(res,max(diameterOfBinaryTree(t->leftChild),diameterOfBinaryTree(t->rightChild))); //经过根节点/不经过
}
int depth(BinTreeNode* t){
if(t == NULL)return 0;
return 1 + max(depth(t->leftChild),depth(t->rightChild));
}
BinTreeNode* pruneTree(BinTreeNode* t){//删除树中的子树中没有1的节点的子树
if(t == NULL)return ;
t->leftChild = pruneTree(t->leftChild);
t->rightChild = pruneTree(t->rightChild);
if(t->leftChild != NULL || t->rightChild != NULL || t->data == '1')return t;
return NULL;
}
//int findTilt(BinTreeNode* t){ //二叉树的坡度(所有节点的左右子树之差绝对值之和)
// if(t == NULL)return 0;
// return abs(treesum(t->leftChild),treesum(t->rightChild)) + findTilt(t->leftChild) + findTilt(t->rightChild);
//}
//int treesum(BinTreeNode* t){
// if(t == NULL)return 0;
// return t->data + treesum(t->leftChild) + treesum(t->rightChild);
//}
//int isBalance(BinTreeNode* t){//判断是否为平衡二叉树
// if(t == NULL)return 1; //左子树平衡 右子树平衡 根节点平衡
// return isBalace(t->leftChild) && isBalance(t->rightChild) && abs(height(t->leftChild)-height(t->rightChild)) <= 1;
//}
//int height(BinTreeNode* t){
// if(t == NULL)return 0;
// return max(height(t->leftChild),height(t->rightChild)) + 1;
//}
int JudgeBST(BinTreeNode* t){//判断是否是树利用中序遍历,前一个值比后一个小
int b1,b2;
if(t == NULL)return 1;
else{
b1 = JudgeBST(t->leftChild);
if(!b1 || predt >= t->data){//如果左子树不是树,或前驱结点比当前节点值大或等则不是树
return 0;
}
predt = t->data;//predt表示前驱结点值
b2 = JudgeBST(t->rightChild);
return b2;
}
}
void outPut(BinTreeNode* t,char k){//输出树大于等于k的结点从大到小输出,根据树特性先遍历右在左
if(t == NULL)return ;
if(t->rightChild != NULL){
outPut(t->rightChild,k);
}
if(t->data >= k)printf("%c ",t->data);
if(t->leftChild != NULL){
outPut(t->leftChild,k);
}
}
BinTreeNode* Search_Small(BinTreeNode* t,int k){//寻找树第k小结点
if(t < 1 || k > t->count)return NULL;//count表示以该节点为跟的结点个数 k表示第k小
if(t->leftChild == NULL){
if(k == 1)return t;
else return Search_Small(t->rightChild,k-1);
}else{
if(t->leftChild->k == k-1)return t;
if(t->leftChild->k < k-1)return Search_Small(t->rightChild,k-(t->leftChild->count+1));
if(t->leftChild->k > k-1)return Search_Small(t->leftChild,k);
}
}
void bstinsert(BinTreeNode* bt,int key)//建立二叉排序树
{
if(bt == NULL)
{
bt = (BinTreeNode*)malloc(sizeof(struct BinTreeNode));
bt->data=key;
bt->leftChild=bt->rightChild=NULL;
}else if(bt->data>key)
{
bstinsert(bt->leftChild,key);
}else
{
bstinsert(bt->rightChild,key);
}
}
void count_k_yezi(BinTreeNode* t,int k){//统计第k层叶子节点个数,count全局变量
if(k == 1 && t->leftChild == NULL && t->rightChild == NULL)count++;
if(t->leftChild)count_k_yezi(t->leftChild,k-1);
if(t->rightChild)count_k_yezi(t->rightChild,k-1);
}
int LeafKLevel(BinTreeNode* t,int k){//统计第k层结点个数
PreOrderll(t,1,k);
return 0;
}
void PreOrderll(BinTreeNode* t,int deep,int k){
if(deep < k){
if(t->leftChild){
PreOrderll(t->leftChild,deep+1,k);
}
if(t->rightChild){
PreOrderll(t->rightChild,deep+1,k);
}
}else if(deep == k && t->leftChild == NULL && t->rightChild == NULL)count++;
}
二叉树的基本操作
于 2023-08-19 21:04:52 首次发布