数据结构——树和二叉树

树形结构是一类重要的非线性结构,在这种结构中一个结点最多只能有一个直接前驱,但可有0个或多个后继。直观地看,树是以分支关系定义的层次结构。树形结构在日常生活中广泛存在,如社会组织机构、家族关系,且在计算机领域也有广泛的也诶他,如文件系统、编译系统、目录组织等方面。
示例:

1. 判断二叉树是否是完全二叉树

【问题描述】

完全二叉树是指在一棵二叉树中除最后一层外,其余层都是满的,并且最后一层或者是满的,或者在右边缺少连续若干结点。

【算法描述】

要判定一棵二叉树是否完全二叉树,应先建立一棵二叉树,此例采用链式存储结构的先序算法建立一棵二叉树。判定一棵二叉树是否是完全二叉树,可以使用队列,在层次遍历的过程中利用完全二叉树“若某结点无左孩子,就一定没有右孩子”的原则进行判断。

#include <stdio.h>
#include <stdlib.h>

typedef char ElementType;
typedef struct node
{
    ElementType data;
    struct node *LChild,*RChild;
}BinNode, *BinTree;

void CreateBinTree(BinTree *root)
{
    char ch;
    ch=getchar();
    if (ch=='#')
        *root=NULL;
    else
    {
        *root=(BinTree)malloc(sizeof(BinNode));
        (*root)->data=ch;
        CreateBinTree(&((*root)->LChild));
        CreateBinTree(&((*root)->RChild));
    }
}

int JudgeComplete(BinTree bt)
{
    int tag=0,front,rear;
    BinTree p=bt,Q[50];
    if(p==NULL)
        return 1;
    front=rear=0;
    Q[++rear]=p;
    while(front!=rear)
    {
        p=Q[++front];
        if(p->LChild&&!tag)
            Q[++rear]=p->LChild;
        else if(p->LChild)
            return 0;
        else
            tag=1;
        if(p->RChild&&!tag)
            Q[++rear]=p->RChild;
        else if(p->RChild)
            return 0;
        else
            tag=1;
    }
    return 1;
}

int main()
{
    int y;
    BinTree bt;
    printf("please input jiedian data:");
    CreateBinTree(&bt);
    y=JudgeComplete(bt);
    if(y==1)
        printf("yes,it is\n");
    else
        printf("no,it isn't\n");
    return 0;
}

运行结果:

 

 

2. 用链式存储结构建立一棵排序二叉树

【问题描述】

建立一个排序二叉树,用链式存储结构建立一棵排序二叉树。所谓排序二叉树,就是将各结点数据元素顺序插到一棵二叉树中,即在插入过程中,始终保持二叉树中每个结点的值都大于其左子树上每个结点的值,小于或等于其右子树上每个结点的值,每个结点存放结点值及左右孩子的指针。

【算法描述】

程序执行过程中,bt 指针始终指向根结点,p 指针指向当前已找到的结点,q 指针不断向下寻找新的结点。插入可用下面的方法进行:

(1) 若二叉排序树是空树,则插入结点为二叉排序树的根;

(2) 若二叉排序树非空,则将关键字值与二叉排序树的根进行比较,若小于根结点的值,则插入左子树,若大于根结点的值,则插入右子树。

#include <stdio.h>
#include <stdlib.h>


#define null 0
int counter=0;
typedef struct btreenode
{
    int data ;
    struct btreenode * lchild;
    struct btreenode * rchild;
} bnode;

bnode * creat(int x,bnode * lbt,bnode * rbt)
{
    bnode * p;
    p=(bnode *)malloc(sizeof(bnode));
    p->data=x;
    p->lchild=lbt;
    p->rchild=rbt;
    return(p);
}

bnode * ins_lchild(bnode *p,int x)
{
    bnode * q;
    if(p== null)
    {
        printf("illgeal insert");
        return null;
    }
    else
    {
        q=(bnode *)malloc(sizeof(bnode));
        q->data=x;
        q->lchild=null;
        q->rchild=null;
        if(p->lchild!=null)
            q->rchild=p->lchild;
        p->lchild=q;
    }
    return q;
}

bnode * ins_rchild(bnode * p,int x)
{
    bnode * q;
    if (p==null)
    {
        printf("illgeal insert");
        return null;
    }
    else
    {
        q=(bnode *)malloc(sizeof(bnode));
        q->data=x;
        q->lchild=null;
        q->rchild=null;
        if(p->rchild!=null)
            q->lchild=p->rchild;
        p->rchild=q;
    }
    return q;
}

void prorder(bnode * p)
{
    if(p==null)
        return;
    printf("%d\t%u\t%d\t%u\t%u\n",++counter,p,p->data,p->lchild,p->rchild);
    if (p->lchild!=null)
        prorder(p->lchild);
    if(p->rchild!=null)
        prorder(p->rchild);
}

int main()
{
    bnode *bt, *p, *q;
    int x;
    printf("input root :");
    scanf("%d",&x);
    p=creat(x,null,null);
    bt=p;
    scanf("%d",&x);
    while(x!=-1)
    {
        p=bt;
        q=p;
        while(x!=p->data&&q!=null)
        {
            p=q;
            if(x<p->data)
                q=p->lchild;
            else
                q=p->rchild;
        }
        if(x==p->data)
        {
            printf("该元素已插入到二叉树中。");
            return null;
        }
        else
            if(x<p->data)
                ins_lchild(p,x);
            else
                ins_rchild(p,x);
        scanf("%d",&x);
    }
    p=bt;
    printf("structure of binary tree:\n");
    printf("number\taddress\tdata\tlchild\trchild\n");
    prorder(p);
    return 0;
}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值