渣渣渣变渣渣系列(9)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jeffscott/article/details/70880605

一、题目描述:

二叉树采用左右链存储,完成以下算法,要求算法尽可能的高效:
1)判断二叉树是否为完全二叉树。
2)输入二叉树的倒数第K个叶子节点。

二、算法思想:

1)判断二叉树树是否为完全二叉树,可以采用反证法,当存在一个节点有且只有一个孩子时,则该二叉树不为完全二叉树,否则为完全二叉树。
2)只需要按先序遍历二叉树,当遇到叶子节点就入栈,然后Pop第K个元素即可。

三、核心代码:

int Iscomplete(BiTree T)//判断是否是完全二叉树
{
    if(T){//如果存在一个节点的左右孩子有且只有一个,则可判读该树不是完全二叉树
       if((T->lchild==0&&T->rchild!=0)||(T->lchild!=0&&T->rchild==0))
        return 0;
       Iscomplete(T->lchild);
       Iscomplete(T->rchild);
    }
}
void K_leaf(BiTree T,int k)//输出倒数第K个叶子节点
{
    int i;
    Stack s;
    InitStack(&s);//初始化栈
    PreOrderT(T,&s);//将先序遍历二叉树,遇到叶子节点则压栈
    for(i=0;i<k-1;i++)
    {
        Dtop(&s);//删除栈顶元素
    }
    printf("the value is:%d",Pop(&s));//打印栈顶元素
}

四、完整代码:

#include <stdio.h>
#include<stdlib.h>
#define ElemType int
#define INFINITY 65535 //β值表示无穷大
#define MAXSIZE 1000 //栈的最大空间
//节点声明,数据域、左孩子指针、右孩子指针
typedef struct BiTNode{
    int data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//栈的结构声明
typedef struct{
    ElemType data[MAXSIZE]; //栈的大小
    int top;   //栈顶的游标
}Stack;

/*二叉树的有关操作声明*/
BiTree CreateBiTree();//建立一棵二叉树
void PreOrderTraverse(BiTree T);//先序遍历一棵二叉树
int Iscomplete(BiTree T);//判断是否是完全二叉树
void K_leaf(BiTree T,int k);//输出倒数第K个叶子节点
void PreOrderT(BiTree T,Stack*s);//先序遍历一棵二叉树,如果遇到叶子节点则入栈
/*栈的有关操作声明*/
void InitStack(Stack *s); //初始化栈
bool IsEmpty(Stack *s); //判断栈是否为空
ElemType Pop(Stack *s); //返回并删除栈顶的元素
void Push(Stack *s,ElemType e); //将元素e压栈
void Dtop(Stack *s);
/*主函数的实现*/
int main(){
    BiTree T;
    int k;
    printf("请按先序遍历的顺序输入一棵树,以-1表示空\n");
    T = CreateBiTree();//建立
    PreOrderTraverse(T);//输出
    printf("\n");
    /*判断是否是二叉树*/
    if(Iscomplete(T))
        printf("是完全二叉树\n");
    else
        printf("不是完全二叉树\n");
   /*输出倒数第K个叶子节点*/
    printf("please input the k:");
    scanf("%d",&k);
    printf("\n倒数第%d个叶子节点为:",k);
    K_leaf(T,k);
    return 0;
}
//先序建立二叉树
BiTree CreateBiTree(){
    int ch;
    BiTree T;
    scanf("%d",&ch);
    if(ch==-1)
        return NULL;
    else{
        T = (BiTree)malloc(sizeof(BiTNode));//动态申请内存
        T->data = ch;
        T->lchild = CreateBiTree();
        T->rchild = CreateBiTree();
    }
    return T;//返回根节点
}
//先序遍历二叉树
void PreOrderTraverse(BiTree T){
    if(T){
       printf("%-3d",T->data);
       PreOrderTraverse(T->lchild);
       PreOrderTraverse(T->rchild);
    }
}
int Iscomplete(BiTree T)//判断是否是完全二叉树
{
    if(T){//如果存在一个节点的左右孩子有且只有一个,则可判读该树不是完全二叉树
       if((T->lchild==0&&T->rchild!=0)||(T->lchild!=0&&T->rchild==0))
        return 0;
       Iscomplete(T->lchild);
       Iscomplete(T->rchild);
    }
}
void K_leaf(BiTree T,int k)//输出倒数第K个叶子节点
{
    int i;
    Stack s;
    InitStack(&s);
    PreOrderT(T,&s);/*将二叉树按先序遍历的顺序压栈 */
    for(i=0;i<k-1;i++)
    {
        Dtop(&s);
    }
    printf("the value is:%d",Pop(&s));
}

void PreOrderT(BiTree T,Stack*s)//先序遍历一棵二叉树,并将每一步结果压栈
{
    if(T)
    {
        if(T->lchild==NULL&&T->rchild==NULL)//如果是叶子节点,就入栈
       Push(s,T->data);
       PreOrderT(T->lchild,s);
       PreOrderT(T->rchild,s);
    }
}

/*栈的有关实现*/
void InitStack(Stack *s) //初始化栈
{
    s->top = -1;
}
bool IsEmpty(Stack *s) //判断栈是否为空
{
    if(s->top == -1)
        return true;
    return false;
}
ElemType Pop(Stack *s) //返回并删除栈顶的元素
{
    if(!IsEmpty(s))
        return s->data[s->top--];
    return INFINITY;
}
void Dtop(Stack *s) //删除栈顶的元素
{
    if(!IsEmpty(s))
        s->top--;
}
void Push(Stack *s,ElemType e) //将元素压栈
{
    if(s->top >= MAXSIZE - 1)
        return;
    s->top++;
    s->data[s->top] = e;
}

五、测试分析:

猜你喜欢

转载自blog.csdn.net/jeffscott/article/details/70880605