数据结构的学习

来源:互联网 发布:进入mysql数据库表命令 编辑:程序博客网 时间:2024/06/04 20:05
//邻接表存储结构定义#define MAXVEX 100struct 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  100int 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 100typedef 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 100BTree 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//设二叉树中最长路径上结点个数不超过Nvoid 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
原创粉丝点击