2021 广工 Anyview 数据结构第 6 章

/**********
【题目】若两棵二叉树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 && !T2) return TRUE;
    else if (T1 && T2) return Similar(T1->lchild, T2->lchild) && Similar(T1->rchild, T2->rchild);
    
    return FALSE; 
}
/**********
【题目】编写递归算法,求对二叉树T先序遍历时
第k个访问的结点的值。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
TElemType VLR(BiTree T, int &resk);
TElemType PreOrderK(BiTree T, int k)
/* 求对二叉树T先序遍历时第k个访问的结点的值。*/
/* 若失败,则返回'#'                         */
{
    int resk = k;
    return VLR(T, resk);
}
TElemType VLR(BiTree T, int &resk)
{
    TElemType res = '#';
    if (T == NULL) return '#';
    if (resk == 1) return T->data;
    resk--;
    if (T->lchild) res = VLR(T->lchild, resk);
    if (T->rchild && res=='#') res = VLR(T->rchild, resk);
    
    return res;
}    
/**********
【题目】编写递归算法,计算二叉树T中叶子结点的数目。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType  data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
int Leaves(BiTree T)
/* 计算二叉树T中叶子结点的数目 */
{
    int res = 0;
    if (!T) return res;
    if (!T->lchild && !T->rchild) return 1;
    
    if (T->lchild) res += Leaves(T->lchild);
    if (T->rchild) res += Leaves(T->rchild);
    
    return res;
}
/**********
【题目】试利用栈及其基本操作写出二叉树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);
    if (T) Push(s, T);
    while (!StackEmpty(s)) {
        BiTree t;
        Pop(s, t);
        visit(t->data);
        if (t->rchild) Push(s, t->rchild);
        if (t->lchild) Push(s, t->lchild);
    }    
}
/**********
【题目】试利用栈及其基本操作写出二叉树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 T, void (*visit)(TElemType))
/* 使用栈,非递归后序遍历二叉树T,     */
/* 对每个结点的元素域data调用函数visit */
{
    SElemType p, child;
    p.ptr = T;
    p.tag = 0;
    Stack s;
    InitStack(s);
    Push(s, p);

    while (!StackEmpty(s)) {     
        GetTop(s, p);
        if (p.tag) {
            visit(p.ptr->data);
            Pop(s, p);
            continue;                    
        } else {
            Pop(s, p);
            p.tag = 1;  // 回溯结点
            Push(s, p);
        } 
        if (p.ptr->rchild) {
            child.ptr = p.ptr->rchild;
            child.tag = 0;  // 首次访问结点
            Push(s, child);
        }
        if (p.ptr->lchild) {
            child.ptr = p.ptr->lchild;
            child.tag = 0;  // 首次访问结点
            Push(s, child);
        }     
    }
}
/**********
【题目】二叉树采用三叉链表的存储结构,试编写
不借助栈的非递归中序遍历算法。
三叉链表类型定义:
typedef struct TriTNode {
  TElemType data;
  struct TriTNode *parent, *lchild, *rchild;
} TriTNode, *TriTree;
**********/
void InOrder(TriTree PT, void (*visit)(TElemType))
/* 不使用栈,非递归中序遍历二叉树PT,  */
/* 对每个结点的元素域data调用函数visit */
{
    TriTree p = PT, last = PT;
    
    while (p) {
        // 上次访问为右结点,直接回溯
        if (last == p->rchild) {
            last = p;
            p = p->parent;
            continue;                  
        } 
        // 上次访问为左结点,则访问父母结点
        else if (last == p->lchild) {  
            last = p;
            visit(p->data);              
            if (p->rchild) p = p->rchild;
            else p = p->parent;
            continue;
        }
        // 遍历左结点
        if (p->lchild) {
            last = p;
            p = p->lchild;
            continue;
        }
        // 无左结点有右结点
        if (!p->lchild && p->rchild) {
            last = p;
            visit(p->data);
            p = p->rchild;
            continue;
        }
        // 叶子结点,访问后回溯
        if (!p->lchild && !p->rchild) {
            last = p;
            visit(p->data);
            p = p->parent;
            continue;
        }
    } 
}
/**********
【题目】假设在三叉链表的结点中增设一个标志域
(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 = T;
    
    while (p) {
        if (p->mark==0) {
            p->mark = 1;
            if (p->lchild) p = p->lchild;
        }        
        else if (p->mark==1) {
            p->mark = 2;
            if (p->rchild) p = p->rchild;
        }
        else {
            visit(p->data);
            p = p->parent;
        }    
    }           
}
/**********
【题目】编写递归算法,将二叉树中所有结点的
左、右子树相互交换。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void ExchangeSubTree(BiTree &T)
/* 将二叉树中所有结点的左、右子树相互交换 */
{
    if (!T) return; 
    if (T->lchild) ExchangeSubTree(T->lchild);
    if (T->rchild) ExchangeSubTree(T->rchild);
    
    swap(T->lchild, T->rchild);
}
/**********
【题目】编写递归算法:求二叉树中以元素值
为x的结点为根的子树的深度。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType data;
  struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
int Depthx(BiTree T, TElemType x)
/* 求二叉树中以值为x的结点为根的子树深度 */
{
    if (!T) return 0;
    int res = 0, depth = 0;
    if (T->data == x) {
        res++;
        if (T->lchild) {
            depth = depth > Depthx(T->lchild, T->lchild->data) ? depth : Depthx(T->lchild, T->lchild->data);
        }    
        if (T->rchild) {
            depth = depth > Depthx(T->rchild, T->rchild->data) ? depth : Depthx(T->rchild, T->rchild->data);
        }    
    } else {
        if (T->lchild) {
            depth = depth > Depthx(T->lchild, x) ? depth : Depthx(T->lchild, x);
        }    
        if (T->rchild) {
            depth = depth > Depthx(T->rchild, x) ? depth : Depthx(T->rchild, x);
        }    
    }    
    
    return res + depth;
}        
/**********
【题目】编写递归算法:对于二叉树中每一个元素值为x
的结点,删去以它为根的子树,并释放相应的空间。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void ReleaseX(BiTree &T, char x)
/* 对于二叉树T中每一个元素值为x的结点, */
/* 删去以它为根的子树,并释放相应的空间 */
{
    if (!T) return;
    if (T->data == x) {
        if (T->lchild) ReleaseX(T->lchild, T->lchild->data);
        if (T->rchild) ReleaseX(T->rchild, T->rchild->data);
        free(T);
    } else {
        if (T->lchild) ReleaseX(T->lchild, x);
        if (T->rchild) 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 T)
/* 判别二叉树T是否为完全二叉树 */
{
    Queue q;
    InitQueue(q);
    
    if (T) EnQueue(q, T);
    else return TRUE;
    int findLeaf = FALSE;
    while (!QueueEmpty(q)) {
        BiTree p;
        DeQueue(q, p);
        
        if (!p->lchild && p->rchild) return FALSE;
        if (findLeaf) {
            // 若叶子结点后还有子树,则非完全二叉树
            if (p->rchild || p->lchild) return FALSE;
        } else {
            // 找到叶子结点
            if (!p->rchild) findLeaf = TRUE;
        }
        if (p->lchild) EnQueue(q, p->lchild);
        if (p->rchild) EnQueue(q, p->rchild);
    }
    
    return TRUE;
}
/**********
【题目】试编写一个二叉排序树的判定算法。
二叉排序树的类型BSTree定义如下:
typedef struct {
  KeyType key;  
  ... ...   // 其他数据域
} TElemType;
typedef struct BiTNode {
  TElemType data;
  struct BSTNode  *lchild, *rchild;
}BSTNode, *BSTree;
**********/
Status IsBSTree(BSTree T)
/* 判别二叉树T是否为二叉排序树。*/
/* 若是,则返回TRUE,否则FALSE  */
{
    if (!T) return TRUE;
    Status res = TRUE;
    if (T->lchild && res) {
        if (T->lchild->data.key < T->data.key && IsBSTree(T->lchild)) res = TRUE;
        else res = FALSE;
    }    
    if (T->rchild && res) {
        if (T->rchild->data.key > T->data.key && IsBSTree(T->rchild)) res = TRUE;
        else res = FALSE;
    }    
    
    return res;
}
/**********
【题目】编写递归算法,从大到小输出给定二叉排序树
中所有关键字不小于x的数据元素。
二叉排序树的类型BSTree定义如下:
typedef struct {
    KeyType key;  
    ... ...   // 其他数据域
} TElemType;
typedef struct BSTNode {
  TElemType  data;
  struct BSTNode *lchild,*rchild;
}BSTNode, *BSTree;
**********/
void OrderOut(BSTree T, KeyType k, void(*visit)(TElemType))
/* 调用visit(T->data)输出  */
{
    if (!T) return;
    OrderOut(T->rchild, k, visit);
    
    if (T->data.key < k) return;    
    else visit(T->data);
    
    OrderOut(T->lchild, k, 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的非递归算法 */
{
    if (!T) return ERROR;
    BSTree cur = T;
    
    while (TRUE) {
        if (k.key == cur->data.key) return ERROR;
        if (k.key < cur->data.key) {
            if (cur->lchild) cur = cur->lchild;
            else {
                cur -> lchild = (BSTree)malloc(sizeof(BSTNode));
                cur -> lchild->data = k;
                return OK;
            }
        }
        
        if (k.key > cur->data.key) {
            if (cur->rchild) cur = cur->rchild;
            else {
                cur->rchild = (BSTree)malloc(sizeof(BSTNode));
                cur->rchild->data = k;
                return OK;
            }
        }
    }
}
/**********
【题目】试编写算法,求二叉树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); 
**********/
Status FindPath(BiTree T, TElemType x, Stack &s);
BiTree CommAncestor(BiTree T, TElemType a, TElemType b)
/* 求二叉树T中结点a和b的最近共同祖先 */
{
    if (!T) return NULL;
    if (a==b) return NULL; 
    Stack s1, s2; 
    SElemType e1, e2;     
    InitStack(s1);
    InitStack(s2);        
        
    if (!FindPath(T, a, s1)) return NULL;
    if (!FindPath(T, b, s2)) return NULL;
    
    // 使长度一致         
    while (StackLength(s1) > StackLength(s2)) Pop(s1, e1); 
    while (StackLength(s1) < StackLength(s2)) Pop(s2, e2);
    
    while (GetTop(s1, e1) && GetTop(s2, e2) && e1.ptr->data != e2.ptr->data) {
        Pop(s1, e1);
        Pop(s2, e2);
    }            
    if (!GetTop(s1, e1) || !GetTop(s2, e2)) return NULL;
    
    return e1.ptr;
}

Status FindPath(BiTree T, TElemType x, Stack &s)
{
    if (T->data==x) return OK;
      
    SElemType e;    
    e.ptr = T;
    
    Push(s, e);    
    if (T->lchild && FindPath(T->lchild, x, s)) return OK;
    if (T->rchild && FindPath(T->rchild, x, s)) return OK;
    // 没有寻找到
    Pop(s, e);
    
    return ERROR;
}
/**********
【题目】在二叉排序树的每个结点中增设一个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 T;    
    if (k == T->lsize) return T;
    if (k < T->lsize) return Ranking(T->lchild, k);
    // 左子树遍历完,则应为右子树的第k-lsize大
    if (k > T->lsize) 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_BF(BBSTree T)
/* 求二叉排序树T的深度,并为每个结点 */
/* 的bf域赋予正确的平衡因子值。      */
{
    if (!T) return 0;  
      
    int left = 0, right = 0;        
    
    if (T->lchild) left = Depth_BF(T->lchild);
    if (T->rchild) right = Depth_BF(T->rchild);
    T->bf = left - right;
    
    return (left > right ? left : right) + 1;
}
/**********
【题目】编写平衡二叉排序树的右平衡处理算法。
平衡二叉排序树的类型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;
   }
}
  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值