/****
【题目】若两棵二叉树T1和T2皆为空,或者皆不空
且T1的左、右子树和T2的左、右子树分别相似,则
称二叉树T1和T2相似。试编写算法,判别给定两棵
二叉树是否相似。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
****/
Status Similar(BiTree T1, BiTree T2)
/* 判断两棵二叉树是否相似的递归算法 */
{
if(T1==NULL&&T2==NULL)
return TRUE;
else if(T1&&T2){
if(Similar(T1->lchild,T2->lchild)==ERROR)
return ERROR;
if(Similar(T1->rchild,T2->rchild)==ERROR)
return ERROR;
}
else
return ERROR;
return TRUE;
}
/****
【题目】编写递归算法,求对二叉树T先序遍历时
第k个访问的结点的值。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
****/
TElemType PreOrderK(BiTree T, int k)
/* 求对二叉树T先序遍历时第k个访问的结点的值。*/
/* 若失败,则返回'#' */
{
int i=0,count=0;
TElemType d;
BiTree a[20],b;
if(k<=0||T==NULL)
return '#';
if(k==1)
return T->data;
d=PreOrderK(T->lchild,k-1);
if(d!='#')
return d;
b=T->lchild;
while(b||i){
if(b){
a[i]=b;
i++;
b=b->lchild;
count++;
}
else{
i--;
b=a[i];
b=b->rchild;
}
}
d=PreOrderK(T->rchild,k-count-1);
if(d!='#')
return d;
else
return '#';
}
/****
【题目】编写递归算法,计算二叉树T中叶子结点的数目。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
****/
int Leaves(BiTree T)
/* 计算二叉树T中叶子结点的数目 */
{
if(T==NULL)
return 0;
else if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else
return Leaves(T->lchild)+Leaves(T->rchild);
}
/****
【题目】试利用栈及其基本操作写出二叉树T的非递归
的先序遍历算法。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用栈类型Stack的相关定义:
typedef BiTree SElemType; // 栈的元素类型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
****/
void PreOrder(BiTree T, void (*visit)(TElemType))
/* 使用栈,非递归先序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
Stack S;
InitStack(S);
BiTree p=T;
while(p){
visit(p->data);
if(p->rchild)
Push(S,p->rchild);
if(p->lchild)
p=p->lchild;
else
if(StackEmpty(S)!=TRUE)
Pop(S,p);
else
p=NULL;
}
}
/**********
【题目】试利用栈及其基本操作写出二叉树T的非递归
的后序遍历算法(提示:为分辨后序遍历时两次进栈的
不同返回点,需在指针进栈时同时将一个标志进栈)。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用栈类型Stack的相关定义:
typedef struct {
struct BiTNode *ptr; // 二叉树结点的指针类型
int tag; // 0..1
} SElemType; // 栈的元素类型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
**********/
void PostOrder(BiTree bt, void (*visit)(TElemType))
/* 使用栈,非递归后序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
Stack S;
InitStack(S);
SElemType e;
BiTree p=bt;
int tag=0;
if(bt){
e.tag=0;
while(!StackEmpty(S)||p==bt){
while(p&&!tag){
e.ptr=p;
if(p->lchild){//如果存在左子树
p=p->lchild;
e.tag=0;
}
else{//否则为右子树
p=p->rchild;
e.tag=1;
}
Push(S,e);
}//while
GetTop(S,e);
if(!StackEmpty(S)&&e.tag){
Pop(S,e); //叶子结点出栈
p=e.ptr;
visit(p->data);//输出该结点
}
if(!StackEmpty(S)){
Pop(S,e); //得到上一层结点
p=e.ptr;
if(e.tag){//右子树已经入栈
visit(p->data);
p=NULL;
}
else{//右子树没入过栈
if(p->rchild){
p=p->rchild;
tag=0;
e.tag=1;
Push(S,e);
}
else{//没有右子树
visit(p->data);
p=NULL;
}
}
}
else{//栈空则,p为NULL
p=NULL;
}
}//while
}//if
}
/**********
【题目】二叉树采用三叉链表的存储结构,试编写
不借助栈的非递归中序遍历算法。
三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *parent, *lchild, *rchild;
} TriTNode, *TriTree;
**********/
void InOrder(TriTree PT, void (*visit)(TElemType))
/* 不使用栈,非递归中序遍历二叉树PT, */
/* 对每个结点的元素域data调用函数visit */
{
TriTree p,pr;
if(PT!=NULL)
{
p = PT;
while(p!=NULL)
{ if(p->lchild==NULL) visit(p->data);
//输出有右子树的结点
if(p->lchild) p = p->lchild;
else
if(p->rchild) p = p->rchild;
else
{
do{
pr = p;
p = p->parent;
if(p->rchild!=pr) //如果pr是p的右子树则不输出
visit(p->data);
}while(p!=NULL&&(p->rchild==pr||NULL==p->rchild));
if(p!=NULL) p = p->rchild;
}
}
}
}
/**********
【题目】假设在三叉链表的结点中增设一个标志域
(mark取值0,1或2)以区分在遍历过程中到达该结点
时应继续向左或向右或访问该结点。试以此存储结
构编写不用栈辅助的二叉树非递归后序遍历算法。
带标志域的三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *lchild, *rchild, *parent;
int mark; // 标志域
} TriTNode, *TriTree;
**********/
void PostOrder(TriTree T, void (*visit)(TElemType))
/* 不使用栈,非递归后序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
TriTree p,pr;
if(T!=NULL)
{
p = T;
while(p!=NULL)
{
if(p->lchild) p = p->lchild;
else
if(p->rchild) p = p->rchild;
else
{
do{
pr = p;
visit(pr->data);
p = p->parent;
}while(p!=NULL&&(p->rchild==pr||NULL==p->rchild));
if(p!=NULL) p = p->rchild;
}
}
}
}
/**********
【题目】编写递归算法,将二叉树中所有结点的
左、右子树相互交换。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void ExchangeSubTree(BiTree &T)
/* 将二叉树中所有结点的左、右子树相互交换 */
{ BiTree p;
if(!T) return;
if(T->lchild) ExchangeSubTree(T->lchild);
if(T->rchild) ExchangeSubTree(T->rchild);
p = T->lchild;
T->lchild = T->rchild;
T->rchild = p;
}
/**********
【题目】编写递归算法:求二叉树中以元素值
为x的结点为根的子树的深度。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
int BirTreeDepth(BiTree T){
int depthLeft,depthRight;
if(null==T) return 0;
else {
depthLeft = BirTreeDepth(T->lchild);
depthRight = BirTreeDepth(T->rchild);
return 1+(depthLeft > depthRight?depthLeft:depthRight);
}
}
int Findx(BiTree T,BiTree &p,TElemType x){
if(T){
if(T->data==x){
p=T;
return 0;
}
else{
Findx(T->lchild,p,x);
Findx(T->rchild,p,x);
}
}
}
int Depthx(BiTree T, TElemType x)
/* 求二叉树中以值为x的结点为根的子树深度*/
{
BiTree p=NULL;
Findx(T,p,x);
return BirTreeDepth(p);
}
/**********
【题目】编写递归算法:对于二叉树中每一个元素值为x
的结点,删去以它为根的子树,并释放相应的空间。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void Destroy(BiTree &T){
if(T){
Destroy(T->lchild);
Destroy(T->rchild);
free(T);
}
}
/*BiTree find(BiTree &T, char x){
if(!T) return null;
if(T->data == x) return T;
find(T->lchild,x); find(T->rchild,x);
} */
void ReleaseX(BiTree &T, char x)
/* 对于二叉树T中每一个元素值为x的结点,*/
/* 删去以它为根的子树,并释放相应的空间 */
{
if(!T) return ;
if(T->data==x)
Destroy(T);
ReleaseX(T->lchild, x);
ReleaseX(T->rchild, x);
}
/**********
【题目】编写复制一棵二叉树的递归算法。
二叉链表类型定义:
typedef char TElemType; // 设二叉树的元素为char类型
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void CopyBiTree(BiTree T, BiTree &TT)
/* 递归复制二叉树T得到TT */
{
if(!T) return ;
TT = (BiTree)malloc(sizeof(BiTNode));
if(!TT) return ;
TT->data = T->data;
if(T->lchild) CopyBiTree(T->lchild,TT->lchild);
if(T->rchild) CopyBiTree(T->rchild,TT->rchild);
}
/**********
【题目】编写算法判别给定二叉树是否为完全二叉树。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用队列类型Queue的相关定义:
typedef BiTree QElemType; // 设队列元素为二叉树的指针类型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);
**********/
Status CompleteBiTree(BiTree bt)
/* 判别二叉树T是否为完全二叉树*/
{ Queue Q;
QElemType p;
int tag=0;
EnQueue(Q,bt);
while(!QueueEmpty(Q))
{
DeQueue(Q,p);
if(!p) tag=1; //如果到最后输出都为空,表示已经遍历完成,确认是完全树
else if(tag) return ERROR;
else
{
EnQueue(Q,p->lchild);
EnQueue(Q,p->rchild);
}
}
return OK;
}
/**********
【题目】试编写一个二叉排序树的判定算法。
二叉排序树的类型BSTree定义如下:
typedef struct {
KeyType key;
... ... // 其他数据域
} TElemType;
typedef struct BiTNode {
TElemType data;
struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;
**********/
Status IsBSTree(BSTree t)
/* 判别二叉树T是否为二叉排序树。*/
/* 若是,则返回TRUE,否则FALSE */
{
BSTree p,q;
if(t)
{ p=t->lchild;
q=t->rchild;
if(p&&p->data.key>=t->data.key)
return FALSE;
if(q&&q->data.key<=t->data.key)
return FALSE;
if (IsBSTree(p))
return IsBSTree(q);
return FALSE;
}
return TRUE;
}
/**********
【题目】编写递归算法,从大到小输出给定二叉排序树
中所有关键字不小于x的数据元素。
二叉排序树的类型BSTree定义如下:
typedef struct {
KeyType key;
... ... // 其他数据域
} TElemType;
typedef struct BSTNode {
TElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode, *BSTree;
**********/
void OrderOut(BSTree t, KeyType x, void(*visit)(TElemType))
/* 调用visit(T->data)输出 */
{ KeyType key = t->data.key;
if(!t)
{
return;
}
if(key>=x)
{
OrderOut(t->rchild,x,visit);
visit(t->data);
OrderOut(t->lchild,x,visit);
}
else
{
OrderOut(t->rchild,x,visit);
}
}
/**********
【题目】试写一非递归算法,在二叉查找树T中插入元素e。
二叉查找树的类型BSTree定义如下:
typedef struct {
KeyType key;
... ... // 其他数据域
} TElemType;
typedef struct BSTNode {
TElemType data;
struct BSTNode *lchild,*rchild;
} BSTNode, *BSTree;
**********/
Status InsertBST_I(BSTree &T, TElemType k)
/* 在二叉查找树T中插入元素e的非递归算法*/
{ BSTree p,L,q = T ;
p = (BSTree)malloc(sizeof(BSTNode));
if(p == NULL) return FALSE;
p->data = k; p->lchild = NULL; p->rchild = NULL;
while(q!=NULL)
{
if(q->data.key == k.key) return FALSE;
if(q->data.key > k.key)
{
if(q->lchild!=NULL) q = q->lchild;
else q->lchild = p;
}
if(q->data.key < k.key)
{
if(q->rchild!=NULL) q = q->rchild;
else q->rchild = p;
}
}
}
/**********
【题目】试编写算法,求二叉树T中结点a和b的最近共同祖先。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用栈类型Stack的相关定义:
typedef struct {
BiTNode *ptr; // 二叉树结点的指针类型
int tag; // 0..1
} SElemType; // 栈的元素类型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
int StackLength(SqStack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
**********/
void findElem(BiTree T,TElemType e,Stack &s)
{
BiTree t=T;
BiTNode *bip;
SElemType se;
while(t)
{
while(t->lchild)
{
if(t->data==e) return ;
se.ptr=t;se.tag=1;
Push(s,se);
t=t->lchild;
}
if(t->data==e) return ;
if(t->rchild) {se.ptr=t;se.tag=1;Push(s,se);t=t->rchild;}
else
{
bip=t;Pop(s,se);t=se.ptr;
while(t->rchild==bip||!t->rchild)
{
bip=t;
if(t!=T) {Pop(s,se);t=se.ptr;}
else return;
}
se.ptr=t;se.tag=1;
Push(s,se);
t=t->rchild;
}
}
}
BiTree CommAncestor(BiTree T, TElemType a, TElemType b)
/* 求二叉树T中结点a和b的最近共同祖先*/
{ Stack sa,sb,st;
SElemType sea,seb;
BiTree bi,bii;
InitStack(sa);InitStack(sb);InitStack(st);
findElem(T,a,sa);
findElem(T,b,sb);
while(!StackEmpty(sa))
{
Pop(sa,sea);
bi=sea.ptr;
st=sb;
while(!StackEmpty(st))
{
Pop(st,seb);
bii=seb.ptr;
if(bi->data==bii->data)return bi;
}
}
}
/**********
【题目】在二叉排序树的每个结点中增设一个lsize域,
其值为该结点的左子树中的结点数加1。试编写时间复杂
度为O(logn)的算法,求树中第k小的结点的位置。
二叉排序树的类型BSTree定义如下:
typedef char KeyType;
typedef struct BSTNode {
KeyType key;
struct BSTNode *lchild,*rchild;
int lsize; // 新增域,值为左子树的结点数+1
} BSTNode, *BSTree;
**********/
BSTNode *Ranking(BSTree T, int k)
/* 在含lsize域的二叉排序树T中,*/
/* 求指向T中第k小的结点的指针 */
{ if(!T) return null;
if(T->lsize==k) return T;
else if(T->lsize>k) return Ranking(T->lchild, k) ;
else return Ranking(T->rchild, k-T->lsize);
}
/**********
【题目】假设二叉排序树T的每个结点的平衡因子域bf当前
均为0。试编写算法,求二叉排序树T的深度,并为每个结点
的bf域赋予正确的平衡因子值。
平衡二叉排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
int bf; // 平衡因子
struct BBSTNode *lchild,*rchild;
} BBSTNode, *BBSTree;
**********/
/*int depth(BBSTree t){
int l;
int r;
if(!t) return 0;
else {
l = depth(t->lchild);
r = depth(t->rchild);
return 1+(l>r?l:r);
}
} */
int Depth_BF(BBSTree T)
/* 求二叉排序树T的深度,并为每个结点*/
/* 的bf域赋予正确的平衡因子值。 */
{ int l,r;
if(!T) return 0;
else {
l = Depth_BF(T->lchild);
r = Depth_BF(T->rchild);
T->bf = l-r;
return 1+(l>r?l:r);
}
}
/**********
【题目】编写平衡二叉排序树的右平衡处理算法。
平衡二叉排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
int bf; // 平衡因子
struct BBSTNode *lchild,*rchild;
} BBSTNode, *BBSTree;
可调用下列旋转调整操作:
void L_Rotate(BBSTree &p); // 对最小失衡子树p做左旋调整
void R_Rotate(BBSTree &p); // 对最小失衡子树p做右旋调整
**********/
void RightBalance(BBSTree &T)
/* 实现对二叉树T的右平衡处理*/
{
BBSTree lc,rd;
rd = T->rchild;
switch(rd->bf){
case RH:
T->bf = rd->bf = EH; L_Rotate(T); break;
case LH:
lc = rd->lchild;
switch(lc->bf){
case LH: T->bf = EH; lc->bf = EH; break;
case EH: T->bf = rd->bf = EH;break;
case RH: T->bf=LH; lc->bf = EH; break;
}
lc->bf=EH;
R_Rotate(T->rchild);
L_Rotate(T);
break;
}
}
/**********
【题目】试编写算法,对一棵以孩子兄弟链表表示
的树统计叶子的个数。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
void Count(CSTree T, int &n){
if(T){
if(!T->firstChild) n++;
Count(T->firstChild, n);
Count(T->nextSibling, n);
}
}
int Leave(CSTree T) /* 统计树T的叶子数*/
{
int n =0;
Count(T , n);
return n;
}
/**********
【题目】试编写算法,求一棵以孩子兄弟链表表示的树的度。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int Degree(CSTree T) /* 求树T的度*/
{
int ds,dt,d;
CSTree p;
if(!T) return 0;
else { ds=0;dt=0;
for( p = T->firstChild; p ; p= p->nextSibling){
dt++;
d= Degree(p);
if(d>ds) ds =d;
}
return ds>dt?ds:dt;
}
}
/**********
【题目】试编写算法,对以双亲表示法存储的树计算深度。
typedef struct {
TElemType data;
int parent; // 双亲位置
} PTNode; // 结点类型
typedef struct {
PTNode nodes[MAX_TREE_SIZE]; // 结点存储空间
int n, r; // 结点数和根的位置
} PTree;
**********/
int PTreeDepth(PTree T) /* 求树T的深度*/
{
int maxdep = 0,i,dep,j;
for(i=0; i<T.n;i++){
dep=0;
for(j =i; j>0; j=T.nodes[j].parent) dep++;
if(dep>maxdep) maxdep = dep;
}
return maxdep+1;
}
/**********
【题目】试编写算法,对以双亲孩子表示法存储的树计算深度。
孩子链表类型定义:
typedef struct ChildNode { // 孩子结点
int childIndex;
struct ChildNode *nextChild;
} ChildNode; // 孩子结点类型
typedef struct {
TElemType data;
int parent; // 双亲位置
struct ChildNode *firstChild; // 孩子链表头指针
} PCTreeNode; // 结点类型
typedef struct {
PCTreeNode *nodes; // 结点存储空间
int n, r; // 结点数和根的位置
} PCTree;
**********/
int fun(PCTree T, int pos)
{
if(T.nodes[pos].firstChild == NULL) return 1;
ChildNode *temp = T.nodes[pos].firstChild;
int depth = 1, max = 1;
while(temp != NULL)
{
if( T.nodes[temp->childIndex].firstChild != NULL)
{
depth = fun(T, temp->childIndex);
if(depth > max)
max = depth;
}
temp = temp->nextChild;
}
return max + 1;
}
int PCTreeDepth(PCTree T) /* 求树T的深度*/
{
int depth;
depth = fun(T, T.r);
return depth;
}
/**********
【题目】试编写算法,对以孩子-兄弟链表表示的树计算深度。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
int TreeDepth(CSTree T)
/* 求树T的深度*/
{
int dep1,dep2,dep;
if(!T) dep=0;
else{
dep1 = TreeDepth(T->firstChild);
dep2 = TreeDepth(T->nextSibling);
dep = dep1+1>dep2?dep1+1:dep2;
}
return dep;
}
/**********
【题目】已知一棵树的由根至叶子结点按层次输出的
结点序列及每个结点的度。试编写算法,构造此树的
孩子兄弟链表。
孩子兄弟链表类型定义:
typedef struct CSTNode {
TElemType data;
struct CSTNode *firstChild, *nextSibling;
} CSTNode, *CSTree;
**********/
CSTree CreateCSTNode(char e) {
CSTNode *p = NULL;
p = (CSTNode*)malloc(sizeof(CSTNode));
p->data = e;
p->firstChild = NULL;
p->nextSibling = NULL;
return p;
}
void BuildCSTree(CSTree &T, char *node, int *degree)
/* 由结点的层序序列node和各结点的度degree构造树的孩子兄弟链表T */
{
int i, j, present=1;
CSTree Tree[50];
if(NULL == node) {
return;
}
Tree[0] = CreateCSTNode(node[0]);
T = Tree[0];
for(i=0; node[i]!='\0'; i++) {
if(degree[i]!=0) {
Tree[present] = CreateCSTNode(node[present]);
Tree[i]->firstChild = Tree[present];
present ++;
for(j=2; j<=degree[i]; j++) {
Tree[present] = CreateCSTNode(node[present]);
Tree[present-1]->nextSibling = Tree[present];
present ++;
}
}
}
}
更多请查看我的个人博客:https://beatjerome.github.io