//邻接表存储结构定义
#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);
}
}
数据结构的学习
最新推荐文章于 2021-11-29 21:23:51 发布