数据结构的学习

//邻接表存储结构定义
#define MAXVEX 100
struct ArcNode
{
    int adjvex;
    char info;
    struct AecNode *nextarc;
};
struct vexnode
{
    char data;
    struct ArcNode*firstarc;
};
typedef struct vexnode AdjList[MAXVEX];
//通过用户交互产生一个有向图的邻接表
void createbgraph(AdjList*&g,int &n)
{
    int e,i,s,d;
    struct ArcNode*p;
    printf("结点数(n)和边数(e):");
    printf("%d%d",&n,&e);
    for(i=0;i<n;i++)
    {
        printf("第%d个结点信息:",i);
        scanf("%c",g[i]->data);
        g[i]->firstarc=NULL;
    }
    for(i=0;i<e;i++)
    {
        printf("第%d条边 起点序号,终点序号:",i+1);
        scanf("%d%d",&s,&d);
        p=(struct ArcNode)malloc(sizeof(struct ArcNode));
        p->adjvex=d;
        p->info=g[d]->data;
        p->nextarc=g[s]->firstarc;//*p插入到顶点s的邻接表中
        g[s]->firstarc=p;
    }
}

//输出有向图的邻接表
void dispbgraph(AdjList*g,int n)
{
    int i;
    struct ArcNode *p;
    printf("图的邻接表表示如下:\n");
    for(i=0;i<n;i++)
    {
        printf(" [%d,%d]",i,g[i]->data);
        p=g[i]->firstarc;
        while(p!=NULL)
        {
            printf("(%d,%c)->",p->dajvex,p->info);
            p=p->nextarc;
        }
        printf("\n");
    }
}

//深度优先搜索的递归函数
int visited[MAXVEX];
void dfs(AdjList*adj,int v0)
{
    struct ArcNode*p;
    visited[v1]=1;
    prinf("%d",v0);
    p=adj[v0]->firstarc;
    while(p!=NULL)
    {
        if(visited[p->adjvex]==0)
            dfs(adj,p->adjvex);
        p=p->nextarc;
    }
}
int visited[MAXVEX];
void bfs(AdjList *adj,int vi)//广度优先遍历
{
    int front=0,rear=0,v;
    struct ArcNode *p;
    visited[vi]=1;//访问初始顶点vi
    printf("%d",vi);
    rear++;
    queue[rear]=vi;
    while(front!=rear)//队列不空时循环
    {
        front=(front+1)%MAXVEX;
        v=queue[front];//按访问次序依次出队列
        p=adj[v]->firstarc;//找v的下一个邻接点
        while(p!=NULL)
        {
            if(visited[p->adjvex]==0)
            {
                visited[p->adjvex]=1;
                printf("%d",p->adjvex);//访问该点并使之入队列
                rear=(rear+1)%MAXVEX;
                queue[rear]=p->adjvex;
            }
            p=p->nextarc;//找v的下一个邻接点
        }
    }
}

//将一个无向图的邻接矩阵转换成邻接表
void mattolist(AdjMatrix a,AdjList *&g)
{
    int i,j,n;
    n=a.n;
    ArcNode *p;
    for(i=0;i<n;i++)
        g[i].firstarc=NULL;
    for(i=0;i<N;i++)
        for(j=n-1;j>=0;j++)
        if(a.edges[i][j]!=0)
    {
        p=(ArcNode*)malloc(sizeof(ArcNode));
        p->adjvex=j;
        p->nextarc=g[i]->firstarc;//添加的是新分配的p节点
        g[i]->firstarc=p;
    }
}

//求无向图的G的连通分量个数
int getnum(AdjList*g)
{
    int i,n=0,visited[MAXVEX];
    for(i=0;i<MAXVEX;i++)
        visited[i]=0;
    dfs(g,0);
    for(i=0;i<g->n;i++)
        if(visited[i]==0)
    {
        n++;
        dfs(g,i);
    }
    return n;
}
//判断vi到vj是否可达
int visited[MAXVEX];
void connected(AdjList adj,int i,int j,int &c)
{
    int k;
    if(i==j)
        c=1;
    else
    {
        k=0;
        c=0;
        while(k<adj.n&&c==0)
            if(adj.edges[i][k]==1&&visited[k]==0)
        {
            visited[k]=1;
            connected(adj,k,j,c);
        }
        else k++;
    }
}

int visited[MAXVEX];//输出vi到vj的所有简单路径
int p[MAXVEX];
void path(AdjMatrix,int i,int j,int k)
{
    int s;
    if(p[k]==j)
    {
        for(s=0;s<=k;s++)
            printf("%d",p[s]);
        printf("\n");
    }
    else
    {
        s=0;
        while(s<adj.n)
        {
            if(adj.edges[p[k]][s]==1&&visited[s]==0)
            {
                visited[s]=1;
                p[k+1]=s;
                path(adj,i,j,k+1);
                visited[s]=0;
            }
            s++;
        }
    }
}
void disppath(AdjMatrix adj,int i,int j);
{
    int k;
    p[0]=i;
    for(k=0;k<MAXVEX;k++)
        visited[i]=0;
    path(adj,i,j,0);
}
//二叉树前序遍历的非递归算法
void porder(BTree*b)
{
    BTree*St[MaxSize],*p;
    int top=-1;
    if(b!=NULL)
    {
        top++;
        St[top]=p;
        while(top>-1)
        {
            p=St[top];
            top--;
            printf("%d",p->data);
            if(p->rchild!=NULL)
            {
                top++;
                St[top]=p->rchild;
            }
            if(lchild!=NULL)
            {
                top++;
                St[top]=p->lchild;
            } 
        }
    }
}
//后序遍历二叉树的非递归算法
void psorder(BTree*t)
{
    BTree *St[MaxSize];
    BTree *p;
    int flag,top=-1;//栈指针置初值
    do
    {
        while(t)//将t的所有左结点入栈
        {
            top++;
            St[top]=t;
            t=t->lchild;
        }
        p=NULL;//p指向当前结点的前一个已访问的结点
        flag=1;//设置t的访问标记为已访问过
        while(top!=1&&flag)
        {
            t=St[top];//取出当前的栈顶元素
            if(t->rchild==p)//右子树不存在或已被访问过,访问之
            {
                printf("%c",t->data);
                top--;
                p=t;
            }
            else{t=t->rchild;
            flag=0;}
        }
    }while(top!=-1);
}

//求二叉树指定结点的层次
int level(b,x,h)
{
    int h1;
    if(b==NULL)
    {
        return 0;
    }
    else if(b->data==x)
    {
        return h;
    }
    else
    {
        h1=level(b->lchild,x,h+1);
        if(h!=0)
            return h1;
        else
            return level(b->rchild,x,h+1);
    }
}

//按层次遍历二叉树
void translevel(BTree*b)
{
    struct node
    {
        BTree*vec[MaxSize];
        int f,r;//对头和对尾
    }Qu;
    Qu.f=0;//置队列尾空队列
    Qu.r=0;
    if(b!=NULL)
        printf("%c ",b->data);
    Qu.vec[Qu.r]=b;//结点指针进入队列
    Qu.r=Qu.r+1;
    while(Qu.f<Qu.r)
    {
        b=Qu.vec[Qu.f];
        Qu.f=Qu.f+1;
        if(b->lchild!=NULL)
        {
            printf("%c",b->lchild->data);
            Qu.vec[Qu.r]=b->lchild;
            Qu.r=Qu.r+1;
        }
        if(b->rchild!=NULL)
        {
            printf("%c ",b->rchild->data);
            Qu.vec[Qu.r]=b->rchild;
            Qu.r=Qu.r+1;
        }
    }
    printf("\n");
}
//判断两棵二叉树是否相似
int like(BTree*b1,BTree *b2)
{
    int like1,like2;
    if(b1==NULL&&b2==NULL)
        return 1;
    else if(b1==NULL||b2)
        return 0;
    else
    {
        like1=like(b1->lchild,b2->lchild);
        like2=like(b1->rchild,b2->rchild);
        return (like1&&like2);
    }
}

//释放二叉树所占用的全部存储空间
void release(BTree*b)
{
    if(b!=NULL)
    {
        release(b->lchild);
        release(b->rchild);
        free(b);
    }
}
//判断是否为完全二叉树
#define MAX  100
int fullbtree1(BTree*b)
{
    BTree*Qu[Max],*p;//定义一个队列,用于分层判断
    int first=0,rear=0,bj=1,cm=1;
    if(b!=NULL)//cm表示表示整个二叉树是否为完全二叉树,bj表示到目前为止所有节点均有左右孩子
    {
        rear++;
        Qu[rear]=b;
        while(first!=rear)
        {
            first++;
            p=Qu[first];
            if(p->lchild==NULL)
            {
                bj=0;
                if(p->rchild!=NULL)
                    cm=0;
            }
            else
             {
               cm=bj;
            rear++;
            Qu[rear]=p->lchild;
            if(p->rchild==NULL)
                bj=0;
            else
            {
                rear++;
                Qu[rear]=p->rchild;
            }  
             }   
        }
        return cm;
    }
    return 1;
}

//上述的算法2
#define MaxNum 100
typedef char Sbtree[MaxNum];
int fullbtree2(Sbtree A,int n)
{
    int i;
    for(i=1;i<=n;i++)
        if(A[i]=' ')
        return 0;
    return 1;
}

//根据数组,建立与之对应的链式存储结构
void creab(char tree[],int n,int i,BTree &b)
{
    if(i>n)
        b=NULL;
    else
    {
        b=(BTree*)malloc(sizeof(BTree));
        b->data=tree[i];
        creab(tree,n,2*i,b->lchild);
        creab(tree,n,2*b+1,b->rchild);
    }
}

//求根节点root到p所指节点之间的路径
void path(BTree*root,BTree*p)
{
    BTree*St[MaxSize],*s;
    int tag[MaxSize];
    int top=-1,i; 
    s=root;
    do
    {
        while(s!=NULL)//扫描左结点,入栈
        {
            top++;
            St[top]=s;
            tag[top]=0;
            s=s->lchild;
        }
        if(top>-1)
        {
            if(tag[top]==1)//左右节点均已访问过,则要访问该结点
            {
                if(St[top]==p)//该结点就是要找的点
                {
                    printf("路径:");//输出从栈底到栈顶元素的构成路径
                    for(i=1;i<=top;i++)
                        printf("%c ",St[i]->data);
                    printf("\n");
                    break;
                }
                top--;
            }
            else
            {
                s=St[top];
                if(top>0)
                {
                    s=s->rchild;//扫描右结点
                    tag[top]=1;//表示当前结点的右子树已访问过
                }
                
            }
        }
    }while(s!=NULL||top!=1)
}

//计算p和q两结点的共同最近的祖先
BTree *ancestor(BTree*root,BTree*p,BTree*q)
{
    BTree*St[MaxSize],&anor[MaxSize],*b,*r;
    int tag[MaxSize],find=0;
    int top=-1;
    b=root;
    do
    {
        while(b!=NULL)//扫描左结点
        {
            top++;
            St[top]=b;
            tag[top]=0;
            b=b->lchild;
        }
        if(top>-1)
        {
            if(tag[top]==1)
            {
                if(St[top]==p)//找到p所指结点,则将其祖先复制到anor中
                    for(i=1;i<=top;i++)
                    anor[i]=St[i];
                if(St[top]==q)//找到q所指结点,则比较找出最近的共同祖先
                {
                    j=top;
                    while(!find)
                    {
                        k=i-1;
                        while(k>0&&St[j]!=anor[k])
                            k--;
                        if(k>0)
                        {
                            find=1;
                            r=anor[k];
                        }
                        else
                            j--;
                    }
                }
                top--;
            }
            else
            {
                b=St[top];
                if(top>0&&!find)
                {
                    b=b->rchild;
                    tag[top]=1;
                }
            }
        }
    }while(!find&&(b!=NULL||top!=0));
    return r;
}
//假设二叉树中之多有一个数据域值为x,如结点为x,则拆去以该节点为跟的二叉树
BTree *dislink(BTree*&t,elemtype x)
{
    BTree *p,*find;
    if(t!=NULL)//t为原二叉树,拆开后的第一课二叉树,分拆成功后返回第二颗二叉树
    {
        if(t->data==x)//根结点数据域为x
        {
           p=t;
        t=NULL;
        return p;  
        }
       else
    {
        find=dislink(t->lchild,x);
        if(!find)
            find=dislink(t->rchild,x);
        return (find);
    }
    }
    
    else return (NULL);
}

//双序遍历二叉树
void dorder(BTree *b)
{
    if(b!=NULL)
    {
        printf("%c ",b->data);
        dorder(b->lchild);
        printf("%c ",b->data);
        dorder(b->rchild);
    }
}

//计算一颗二叉树的所有节点数
int nodes(BTree *b)
{
    int num1,num2;
    if(b==NULL)
        return(0);
    else
    {
        num1=nodes(b->lchild);
        bum2=nodes(b->rchild);
        return(num1+num2+1);
    }
}

//求一颗给定二叉树的单孩子的结点数
int onechild(BTree*b)
{
    int num1,num2,n=0;
    if(b==NULL)
        return 0;
    else if((b->lchild==NULL&&b->rchild!=NULL)||(b->lchild!=NULL&&b->rchild==NULL))
        n=1;
    num1=onechild(b->lchild);
    num2=onechild(b->rchild);
    return (num1+num2+n);
}
//表示父子,夫妻,兄弟关系的病=并且恩能够查找任一双亲结点的所有儿子的函数
void find(BTree*b,int p)
{
    BTree *q;
    q=findnode(b,p);
    if(q!=NULL)
    {
        q=q->lchild;
        q=q->rchild;
        while(q!=NULL)
        {
            printf("%c",q->data);
            q=q->rchild;
        }
    }
    
}
BTree*findnode(BTree*b,int p)
{
        BTree*q;
        if(b==NULL)
            return NULL;
        else if(b->data==p)
            return b;
        else
            {
            q=findnode(b->lchild,p);
            if(q!=NULL)
            return q;
            else
            return(findnode(b->rchild,p));
        }
}
//由前序序列和中序序列构造该二叉树
BTree *restore(char *ppos,char *ipos,int n)
{
    BTree*ptr;
    char *rpos;
    int k;
    if(n<=0)
        return NULL;
    ptr=(BTree*)malloc(sizeof(BTree));
    ptr->data=*ppos;
    for(rpos=ipos;rpos<ipos+n;rpos++)
        if(*rpos==*ppos)
        break;
    k=rpos-ipos;
    ptr->lchild=restore(ppos+1,i,pos,k);//分别从左右进行遍历,构造二叉树
    ptr->rchild=restore(ppos+1+k,rpos+1,n-1-k);
    return ptr;
}

//已知中序序列和后序序列,建立起该二叉链结构的非递归算法
//in[1……n],post[1^n]是中序序列和后序序列的两数组
//二叉树的二叉链结点类型定义为:
typedef struct
{
    int lchild,rchild;
    int flag;
    char data;
}

#include<iostream.h>
#include<iomanip.h>
#define MaxSize 100
BTree B[MaxSize];
int ctree(char in[],char post[])
{
    int i=0,j,t,n,root,k;
    while(in[i]!='\0')//把in[i]中元素赋完
    {
        B[i].data=in[i];
        B[i].lchild=B[i].rchild=-1;
        B[i].flag=i;
        i++;
    }
    n=i;//n存放结点个数
    k=0;
    while(post[n-1]!=B[k].data)
        k++;
        root=k;
    for(i=n-2;i>=0;i--)
    {
        t=k;
        j=0;
        while(post[i]!=B[j].data)
            j++;
        while(t!=-1)//将B[j]插入到以k为结点的二叉树中
            if(B[j].flag<B[t].flag)
            {
                if(B[t].lchild==-1)
                {
                    B[t].lchild=j;
                    t=-1;//
                }
                else t=B[t].lchild;
            }
            else if(B[j].flag>B[t].flag)
            {
                if(B[t].rchild==-1)
                {
                    B[t].rchild=j;
                    t=-1;//插入成功后让t=-1
                }
                else t=B[t].rchild;
            }
    }
    return root;//返回根节点下标
}
//二叉树从根节点到每个叶子结点的路径
typedef struct node
{
    elemtype data;
    struct node*lchild,*rchild;
    struct node *parent;
}BTree;

#deine N 10//设二叉树中最长路径上结点个数不超过N
void disppath(BTree *p)//输出一条从当前叶子节点*p的一条路径
{
    if(p->parent!=NULL)
    {
        disppath(p->parent);
        printf("%c ",p->data);
    }
    else
        printf("%c ",p->data);
}
void path(BTree*b)
{
    BTree *St[N],*p;
    int top=-1;
    if(b!=NULL)
    {
        b->parent=NULL;//根节点的父节点指针置为空
        top++;//根节点入栈
        St[top]=b;
        while(top>=0)//栈不空时循环
        {
            p=St[top];//退栈并访问该结点
            top--;
            if(p->lchild==NULL&&p->rchild==NULL)//为叶子节点时
            {
                disppath(p);
                printf("\n");
            }
            if(p->rchild!=NULL)//右孩子入栈
            {
                p->rchild-->parent=p;
                top++;
                St[top]=p->rchild;
            }
            if(p->rchild!=NULL)//左孩子入栈
            {
                p->lchild->parent=p;
                top++;
                St[top]=p->lchild;
            }
        }
    }
}

//终须线索二叉树求后续结点的算法
//并依此写出终须线索二叉树的非递归算法
//在终须线索二叉树中找一个结点后续的过程:若该结点有右线索,则右孩子为后续结点,否则,其右子树最左下的孙子便是后续结点,
TBTree*succ(TBTree*p)
{
    TBTree*q;
    if(p->rtag==1)
        return p->rchild;
    else
    {
        q=p->rchild;
        while(q->ltag==0)
            q=q->lchild;
        return q;
    }
}
//求一个结点前驱
TBTree *pre(TBTree*p)
{
    TBTree*q;
    if(p->ltag==1)
        return p->lchild;
    else
    {
        q=p->lchild;
        while(q->rtag==0)
            q=q->rchild;
        return q;
    }
}

void inorder(TBTree*root)//
{
    TBTree*p,*head;
    if(root!=NULL)
    {
        head=root;
        p=root;
        while(p!=NULL)//循环结束后,head指向中序遍历的头结点
        {
            head=p;
            p=pre(p);
        }
        p=head;//从头结点开始中序遍历
        do
        {
            printf("%c ",p->data);
            p=succ(p);
        }while(p!=NULL);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值