二叉树的基本操作

来源:互联网 发布:小米note查看网络制式 编辑:程序博客网 时间:2024/06/15 02:10
#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define MAXSIZE 100typedef struct BiTreeNode     //{ int data; struct BiTreeNode*lchild; struct BiTreeNode*rchild;}BTNode,*BiTree;       ////先序建立二叉树void create_BTree(BiTree&T)  //{ElemType data;data=getchar();if(data=='@')           //输入@置空{T=NULL;}else{T=(BiTree)malloc(sizeof(BTNode));   //根,左,右,先序建立二叉树T->data=data;create_BTree(T->lchild);create_BTree(T->rchild);}}//二叉树的先序遍历(递归)void PreOrder(BiTree T){if(T!=NULL){printf("%d",T->data);PreOrder(T->lchild);PreOrder(T->rchild);}}//先序遍历的非递归(根,左,右)借助一个栈void PreOrder_BiTree(BiTree T){Init_Stack(S);                      //初始化栈,p是遍历指针BiTree p=T;while(p||!Stack_Empty(S))           //树非空,栈非空{if(p)                           //输出根节点,根节点入栈,遍历左子树{printf("%d",p->data);Stack_Push(S,p->data);p=p->lchild;}else{Stack_Pop(S,p->data);       //根节点退栈,遍历右子树p=p->rchild;}}}//二叉树的中序遍历void InOrder(BiTree T){if(T!=NULL){printf("%d",T->data);InOrder(T->lchild);InOrder(T->rchild);}}//中序遍历的非递归算法,算法需要借助一个栈void InOrder_BiTree(BiTree T){Init_Stack(S);                      //初始化栈,p是遍历指针BiTree p=T;while(p||!Stack_Empty(S)){if(p){Stack_Push(S,p->data);      //每次遇到非空先向左走p=p->lchild;         }else{Stack_Pop(S,p->data);       //根指针退栈,访问根结点,遍历右子树p=p->rchild;}}}//二叉树的后序遍历(左,右,根)void PostOrder(BiTree T){if(T!=NULL){InOrder(T->lchild);InOrder(T->rchild);printf("%d",T->data);}}//二叉树的后序遍历(非递归)(遍历过程中记得标记左右子树的状态)void PostOrder(BiTree T)      //左右根{SqStack S;BiTree p;BiTree r;Init_Stack(S);p=T;r=NULL;while(p||!Stack_Empty(S)){if(p)                 //最开始,一直向左走{Stack_Push(S,p);p=p->lchild;}else                  //否则,向右{Get_Top(S,p->data);   //读栈顶元素if(p->rchild&&p->lchild!=r)    //如果右子树存在,且未被访问过{p=p->rchild;               //转向右Stack_Push(S,p->data);     //压入栈p=p->lchild;               //再走到最左}else{Stack_Pop(S,p->data);      //弹出printf("%d",p->data);      //访问r=p;                       //记录最近访问的节点p=NULL;}}}}//递归求出树的高度(节点个数,宽度,每层节点个数都与之类似)int Depth_BiTree(BiTree T){int Left_Depth;int Right_Depth;if(T==NULL)return 0;Left_Depth=Depth_BiTree(T->lchild);Right_Depth=Depth_BiTree(T->rchild);if(Left_Depth>Right_Depth){return Left_Depth+1;}else{return Right_Depth+1;}}//return(Left_Depth>Right_Depth)?(Left_Depth+1):(Right_Depth+1);  //加一是根}//非递归求出树的高度(基于层次遍历的思想)//level记录当前节点所在层数,变量last记录当前最右结点,每次层次遍历出队时与last指针相比,两者相等,层数加1,并让last指向下一层最右结点int Depth_Bitree(BiTree T){if(!T)                 //空树,高度为0{return 0;}int front,rear=-1;int last,level=0;      //last指向下一层第一个结点的位置BiTree Q[MAXSIZE];     //设置队列Q,用来存储二叉树结点Q[++rear]=T;           //将根结点入队BiTree p;while(front<rear)      //队列不空,循环{p=Q[++front];      //元素出队,即正在访问的结点if(p->lchild){Q[++rear]=p->lchild;  }if(p->rchild){Q[++rear]=p->rchild;}if(front==last)     //注意每一次遍历的所有元素为该二叉树的一个层级{level++;last=rear;}}}//(补充)二叉树的层次遍历//根结点入队,出队后访问其是否有左右结点(每次出队的元素都是一个层级,访问其是否有左右子树,如此往复)void Level_Order(BiTree T){Init_Queue(Q);BiTree p;En_Queue(Q);while(!Empty_Queue(Q))      //队列不空循环{De_Queue(Q,p);          //队头元素出队printf("%d",p->data);   //访问当前p所指向的位置if(p->lchild!=NULL)     {En_Queue(Q,p->lchild)//左子树不空,左子树入队}if(p->rchild!=NULL){En_Queue(Q,p->rchild)//右子树不空,右子树入队}}}//递归求叶节点个数int leafCountOfBiTree(BiTree T)  {if(T==NULL)          return 0;      if(T->lchild==NULL && T->rchild==NULL)          return 1;      return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);  }  //第归交换左右子树void swap(BiTree T){BiTree temp=NULL;if(T){swap(T->lchild);swap(T->rchild);temp=T->lchild;T->lchild=T->rchild;T->rchild=temp;}}//判断一个树是否为完全二叉树(当遇到空节点,查看其后是否有非空节点)bool Is_Complete(BiTree T){BiTree p;Init_Queue(Q);if(!T)              //空树为完全二叉树{return 1;}EnQueue(Q,T);       //while(Empty_Queue(Q)){DeQueue(Q,p);if(p){EnQueue(Q,p->lchild);EnQueue(Q,p->rchild);}else{while(Empty_Queue(Q)){DeQueue(Q,p);if(p)return 0;}}}return 1;}//线索二叉树的存储结构(引入一个标记域,将非线性结构变为线性结构)typedef struct ThreadNode{ElemType data;                         //数据域struct ThreadNode *lchild,*rchild;     //左右孩子指针int ltag,rtag;                         //左右线索标志}ThreadNode,*ThreadTree;//通过中序遍历对二叉树线索化的递归算法void In_Thread(ThreadTree&p,ThreadTree&pre){if(p!=NULL){In_Thread(p->lchild,pre);if(p->lchild==NULL){p->lchild=pre;p->ltag=1;}if(pre!=NULL&&pre->rchild==NULL){pre->rchild=p;pre->rtag=1;}pre=p;In_Thread(p->rchild,pre);}}

0 0
原创粉丝点击