数据结构-树的进阶代码

来源:互联网 发布:千里眼淘宝数据插件 编辑:程序博客网 时间:2024/06/08 13:39

1.复制一颗二叉树的算法

树的存储结构如下:typedef int ElemType;typedef struct BiTNode{ElemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;复制一颗树bool CopyTreeIsOK(BiTree p){if(CopyTree(p)==NULL)return false;return true;}BiTree CopyTree(BiTree p){if(!p)return NULL;BiTree q=new BiTNode;q->data=p->data;q->lchild=CopyTree(p->lchild);q->rchild=CopyTree(p->rchild);return q;}


2.设二叉树以链式表示,输出二叉树中各节点的数据以及所在层数

void PrintTreeHeighValue(BiTree p){PrintValue(p,0);}void PrintValue(BiTree p,int h){if(!p)return;printf(“The BiTNode data equal %d, The heigh is %d”,p->data,h);PrintValue(p->lchild,h+1);PrintValue(p->rchild,h+1);}


3.判断一颗树是否为二叉排序树

bool isBSTree(BiTree p){if(!p)return true;else if(p->lchild&&p->data<p->lchild->data)return false;else if(p->rchild&&p->data>p->rchild->data)return false;else if(!p->lchild&&!p->rchild)return true;return isBSTree(p->lchild)&&isBSTree(p->rchild);}


4.设计一个算法返回二叉树T的先序序列的最后一个节点的指针,要求采用非递归形式,且不允许用栈。

BiTNode* FindProPointer(BiTree T){BiTNode *p=T;while(1){if(p->rchild)p=p->rchild;else if(p->lchild)p=p->lchild;else if(!p->lchild&&!p->rchild)break;}return p;}


5.在二叉树中查找值为x的结点,要求打印x结点的所有祖先,假设值为x的结点不多于一个。

typedef int Elemtype;void PrintAncestors(BiTree T,const Elemtype x){printf(“The ancestors :”)Ancestors(T,x);}bool Ancestors(BiTree T,const Elemtype x){if(!T)return false;else if(T->data==x)return true;else{bool left=Ancestor(T->lchild,x);bool right=Ancestor(T->rchild,x);if(left||right)printf(“%d\n”,T->data);return (left||right);}}


6.求元素为x节点的子二叉树高度
typedef int ElemType;void FindValue(BiTree T,const ElemType x){if(T){if(T->data==x){printf(“In this BiTree the height is %d when the data equals %d”,GetHeight(T),x);return;}FindValue(T->lchild,x);FindValue(T->rchild,x);}}int GetHeight(BiTree T){if(!T)return;int l= GetHeight(p->lchild);int r=GetHeight(p->rchld);return r>l?(r+1):(l+1)}


7.分别写出下面算法:在中序线索二叉树T中查找给定的结点*p在中序列中序列的前驱和后继。

(1)   中序线索二叉树中查找p的中序前驱结点,并用pre指针返回结果

ThreadNode * InPre(ThreadNode *q){ThreadNode *pre;if(p->ltag==1)//无左孩子pre=p->lchild;else{for(q=p->lchild;q->rtag==0;q=q->rchild);//左子树最右边pre=q;}return pre;}


(2)   在中序线索二叉树T中找结点的中序后继结点

ThreadNode *InSucc(ThreadNode *p){ThreadNode *succ;if(p->rtag==1)succ=p->rchild;else{for(q=p->rchild;q->ltag==0;q=q->lchild);//右子树最左边succ=q;}return succ;}


8.设计一个算法求二叉树的内路径长度和外路径长度。(扩展:求内外路径长度只差的绝对值)

void PathLength(BiTree T){int Ipath=0,Epath=0;PL(t,&Ipath,Epath,0);printf(“%d\t%d”,Ipath,Epath);}void PL(BiTree T, int *Ipath,int *epath,int h){if(!T)return;else if(!T->lchild&&!T->rchild)Epath+=h;elseIpath+=h;PL(T->lchild,Ipath,Epath,h+1);PL(T->rchild,Ipath,Epath,h+1);}


9.设将二叉树的宽度定义为具有结点数量最多的某一层中包含的结点个数。设计一个算法求二叉树的宽度。

#define MaxSize 1024typedef struct SqQueue{ElemType data[MaxSize];int front,rear;}SqQueue;int WeightOfTree(BiTree T){sqQueue Q;//这个队列用来存树的结点BiTNode *p;int maxWeight=0;int curWeight=0;EnQueue(Q,T);for(!IsEmpty(Q)){curWeight=(Q.rear+MaxSize-Q.front)%MaxSize;//队列的宽度if(curWeight>maxWeight)maxWeight=curWeight;for(int i=0;i<curWeight;i++){p=DeQueue(Q);if(p->lchild)EnQueue(Q,p->lchild);if(p->rchild)EnQueue(Q,p->rchild);}}return maxWeight;}


10.设计一个算法判断二叉树是否是完全二叉树(递归和非递归)

非递归:

bool IsComplete(BiTree T){SqQueue Q;BiTNode *p;EnQueue(Q,p);while(!IsEmpty(Q)){p=DeQueue(Q);if(p){EnQueue(Q,p->lchild);EnQueue(Q,p->rchild);}else{while(!IsEmpty(Q)){p=DeQueue(Q);if(!p)return false;}return true;}}}

递归:

bool IsComplete(BiTree T){int h=GetHeight(T);int num=1;for(int i=0;i<h;i++)num=num*2;num--;//满二叉树总结点数BiTNode *A=new BiTNode*[num];for(int i=0;i<num;i++)A[i]=NULL;Map(T,A,0);bool flag=false;for(int i=0;i<num;i++){if(!flag&&A[i]==NULL)flag=true;if(flag&&A[i]!=NULL)return false;}return true;}void Map(BiTree T,BiTNode *A[],int index){if(!T) return;A[index]=T;Map(T->lchild,A,2*index+1);Map(T->rchild,A,2*index+2);}int GetHeight(BiTree T){if(!T)return;int l= GetHeight(p->lchild);int r=GetHeight(p->rchld);return r>l?(r+1):(l+1)}


11.设计一个尽可能快的算法,求出在一颗二叉排序树种关键字大于K的结点的数量。

int Count(BiTree T,int K){if(!T)return 0;if(T->data<=k)return Count(T->rchild);elsereturn Count(T->lchild)+1+Count(T->lchild)+1;}


12.在一棵二叉树中,设p和q分别为二叉树中任意两个结点,编写算法找到p和q的最近公共祖先结点。

bool IsAncestor(BiTree T,BiTNode *x,Stack *S){if(!T)return false;if(T==x||IsAncestor(T->lchild,x,S)||IsAncestor(T->rchild,x,S)){Push(S,T);return true;}return false;}BiTNode *FindNearesAncestor(BiTree T,BiTNode *p,BiTNode *q){BiTNode *tp=NULL,*tq=NULL;Stack Sp,Sq;if(!IsAncestor(T,p,Sp))return NULL;if(!IsAncestor(T,q,Sq))return NULL;while(!IsEmpty(Sp)||!IsEmpty(Sq)){if(tp==tq&&top(Sp)!=top(Sq))return tp;tp=Pop(Sp);tq=Pop(Sq);}}


原创粉丝点击