returnOK;
}//ListTraverse
#defineMAX_TREE_SIZE100
//这里用了动态分配空间new
if(0==S.length)
{//表空
T=NULL;//空树
returnOK;
}
ptr[1]=(BiTNode*)malloc(sizeof(BiTNode));
ptr[1]->data=S.elem[1];//建立树根
T=ptr[1];
for(i=2;i<=S.length-1;i++)
{//依次建立子树
if(0==S.elem[i])
{//数据为0表示无节点,指针为空
ptr[i]=NULL;
}
else
{
ptr[i]=(BiTNode*)malloc(sizeof(BiTNode));
ptr[i]->data=S.elem[i];//
if(i>=S.length/2)
{
//注意这里要对叶节点的左右指针做处理
ptr[i]->lchild=NULL;
ptr[i]->rchild=NULL;
}
}
j=i/2;/找到结点i的双亲j
if(i==j*2)
{//左孩子
if(ptr[j])//判断双亲是否为空
ptr[j]->lchild=ptr[i];//i是j的左孩子
}
else
{//右孩子
if(ptr[j])//判断双亲是否为空
ptr[j]->rchild=ptr[i];//i是j的右孩子
}
}
returnOK;
}//CreateBitree_SqList
//树的遍历//
StatusPreOrderTraverse(BiTreeT)
{//先序遍历二叉树
if(T)
{
cout<data<<"";//访问结点
PreOrderTraverse(T->lchild);//遍历左子树
PreOrderTraverse(T->rchild);//遍历右子树
}
returnOK;
}//PreOrder
typedefstruct{
QElemType*base;//指向树节点的指针数组
intfront;
intrear;
}SqQueue;
StatusInitQueue(SqQueue&Q)
{
Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
if(!
Q.base)exit(OVERFLOW);
Q.front=Q.rear=0;
returnOK;
}//InitQueue
StatusDeQueue(SqQueue&Q,BiTree&p)
//输出p是指针
{
if(Q.front==Q.rear)
returnERROR;
p=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
returnOK;
}//DeQueue
StatusEnQueue(SqQueue&Q,BiTreeT)//输入指针
{
if((Q.rear+1)%MAXQSIZE==Q.front)
returnERROR;
Q.base[Q.rear]=T;
Q.rear=(Q.rear+1)%MAXQSIZE;
returnOK;
}//EnQueue
StatusQueueEmpty(SqQueue&Q)
{
if(Q.front==Q.rear)
returnOK;
returnERROR;
}//QueueEmpty
StatusInOrderTraverse(BiTreeT)
{//中序遍历二叉树
if(T)
{
InOrderTraverse(T->lchild);//遍历左子树
cout<data<<"";//访问结点
InOrderTraverse(T->rchild);//遍历右子树
}
returnOK;
}//InOrder
StatusNextOrderTraverse(BiTreeT)
{//后序遍历二叉树
if(T)
{
NextOrderTraverse(T->lchild);//遍历左子树
NextOrderTraverse(T->rchild);//遍历右cout<data<<"";//访问结点
}
returnOK;
}//NextOrder
intmain()
{inti,j;
TElemTypedata;
cout<<"创建一个二叉树"<BiTreeT;//定义树
SqListS;//顺序表
Initlist_Sq(S);//初始化顺序表
intarr[100]={0};//初始化数组
do{cout<<"输入结点的位置(0时结束)";
cin>>i;
if(i!
=0)
{cout<<"输入结点数据元素(0时结束)";
cin>>data;
while(data==0){//data==0表示节点为空
cout<<"结点位置不为0!
";
cout<<"结点数据元素不为0!
";
cin>>data;
}
if(j
j=i;//找最大节点位置
arr[i]=data;
}
}while(i!
=0);
S.elem=arr;//用数组初始化顺序表
S.length=j+1;//最大节点位置即表长
cout<CreateBiTree_SqList(T,S);
cout<<"先序遍历:
"<PreOrderTraverse(T);
cout<cout<<"中序遍历:
"<InOrderTraverse(T);
cout<cout<<"后序遍历:
"<NextOrderTraverse(T);
cout<returnOK;
}
4.图
图结构是一种比树形结构更复杂的非线性结构。
通常用邻接矩阵或邻接表存储图结构。
所谓邻接矩阵的存储结构就是用一维数组途中结点的信息,用矩阵表示图中各结点的关系。
邻接表则是顺序存储与链式存储相结合。
实现方法:
邻接矩阵:
建立一个一维数组存储图中结点的信息。
两个结点之间若存在边关系则在相
应的矩阵中存入1,否则存入0。
邻接表:
对于图中的每个结点vi,将所有的邻接于vi的顶点vj链成一个单链表,这个单链表就成为顶点vi的邻接表,再将所有的顶点的邻接表的表头放入数组中,构成图的邻接表。
算法实现:
具体参见源程序代码。
程序源代码:
#include
#include
#include
#include
#include
usingnamespacestd;
#defineStatusbool
#defineMAX_VERTEX_NUM20
#defineSTR_LENGTH5
typedefchar*VertexType;
typedefstructArcNode{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
}ArcNode;
typedefstructVNode{
VertexTypedata;//顶点信息字符串指针
ArcNode*firstarc;//指向第一条依附该顶点的弧
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;
//intkind;//图的种类标志
}ALGraph;
StatusInitALGraph(ALGraph&G)
{//图的初始化
inti;
for(i=0;i{//分配空间及指针初始化
G.vertices[i].data=(char*)malloc(STR_LENGTH*sizeof(char));
G.vertices[i].firstarc=NULL;//指针初始化为0
}
returnOK;
}//InitALGraph
intLocateVex(ALGraphG,char*t)
{//查找顶点在邻接表中下标位置
inti;
for(i=0;i{//逐个比较即可
if(strcmp(G.vertices[i].data,t)==0)
returni;
}
return-1;
}//LocateVex
StatusBuild_AdjList(ALGraph&G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接表
{//图的邻接表存储建立
intv,a;
intm;
inti,j;
ArcNode*p,*q;//指针
chart[STR_LENGTH],h[STR_LENGTH];
//临时存储顶点信息的字符串
InitALGraph(G);//初始化
cout<<"输入顶点个数:
";
cin>>v;
while(v<0)
{
cout<<"vcan't<=0!
"<cout<<"输入顶点个数:
";
cin>>v;
}//顶点数不能为负
G.vexnum=v;
cout<<"输入边数:
";
cin>>a;
while(a<0)
{
cout<<"acan't<=0!
"<cout<<"输入边数:
";
cin>>a;
}//边数不能为负
G.arcnum=a;
cout<<"输入各个顶点的信息(字符或字符串):
"<cin.ignore();//忽略换行符
for(m=0;m{
cout<<""<";
cin.getline(G.vertices[m].data,STR_LENGTH);//输入各顶点的符号
}
cout<<"输入各个边的信息(弧头和弧尾):
"<for(m=1;m<=a;m++)
{//输入各个边信息
cout<<""<"<cou