一、二叉树
以下采用链表结构来实现上图的二叉树:
#include <cstdlib>
#include <iostream>
using namespace std;
struct mNode
{
int mData;
struct mNode *left;
struct mNode *right;
};
void PreOrder(mNode *node)
{
if(node!=0)
{
printf("%d\t",node->mData);
PreOrder(node->left);
PreOrder(node->right);
}
}
void InOrder(mNode *node)
{
if(node!=0)
{
InOrder(node->left);
printf("%d\t",node->mData);
InOrder(node->right);
}
}
void PostOrder(mNode *node)
{
if(node!=0)
{
PostOrder(node->left);
PostOrder(node->right);
printf("%d\t",node->mData);
}
}
bool FindElem(mNode *node,int item)
{
if(node==0)
return false;
if(node->mData==item)
return true;
return FindElem(node->left,item)||FindElem(node->right,item);
}
int main(int argc, char *argv[])
{
struct mNode *node1=new struct mNode;
node1->mData=1;
struct mNode *node2=new struct mNode;
node2->mData=2;
struct mNode *node3=new struct mNode;
node3->mData=3;
struct mNode *node4=new struct mNode;
node4->mData=4;
struct mNode *node5=new struct mNode;
node5->mData=5;
node1->left=node2;
node1->right=node5;
node2->left=node3;
node2->right=node4;
node3->left=node3->right=node4->left=node4->right=node5->left=node5->right=0;
PreOrder(node1);
printf("\n");
if(FindElem(node1,1))
printf("true\n");
else
printf("false\n");
system("PAUSE");
return EXIT_SUCCESS;
}
二、二叉搜索树
二叉树中有一种特殊的树,名为二叉搜索树,这样的一棵树同样可以采用链表来表示,其中每个结点包含left和right指向结点的左孩子和右孩子。二叉搜索树的特点是,对于任何结点x,其左子树的关键字最大不超过x.key,其右子树的关键字不低于x.key。大部分二叉搜索树的最坏运行时间与树的高度成正比。
#include <cstdlib>
#include <iostream>
using namespace std;
struct mNode
{
int mData;
struct mNode *left;
struct mNode *right;
};
void InOrder(mNode *r)
{
if(r!=0)
{
InOrder(r->left);
printf("%d\t",r->mData);
InOrder(r->right);
}
}
bool FindElem(mNode *r,int item)
{
if(r==0)
return false;
if(r->mData==item)
return true;
if(r->mData>item)
return FindElem(r->left,item);
else
return FindElem(r->right,item);
}
void InsertElem(mNode *&r,int item)
{
struct mNode *pNew=new struct mNode;
pNew->mData=item;
pNew->left=0;
pNew->right=0;
struct mNode *p=r;
struct mNode *q=0;
while(p!=0)
{
q=p;
if(p->mData>item)
p=p->left;
else
p=p->right;
}
if(q==0)
r=pNew;
else
{
if(q->mData>item)
q->left=pNew;
else
q->right=pNew;
}
}
bool DeleteElem(mNode *&r,int item)
{
mNode *p=r;
mNode *q=0;
while(p!=0)
{
if(p->mData==item)
break;
q=p;
if(p->mData>item)
p=p->left;
else
p=p->right;
}
if(p==0)
return false;
if(p->left==0&&p->right==0)
{
if(q==0)
r=0;
else if(q->mData>p->mData)
q->left=0;
else
q->right=0;
delete p;
}
else if(p->left!=0&&p->right==0)
{
if(q==0)
r=r->left;
else if(q->mData>p->mData)
q->left=p->left;
else
q->right=p->left;
delete p;
}
else if(p->left==0&&p->right!=0)
{
if(q==0)
r=r->right;
else if(q->mData>p->mData)
q->left=p->right;
else
q->right=p->right;
delete p;
}
else
{
mNode *temp=p->left;
while(temp->right!=0)
{
temp=temp->right;
}
temp->right=p->right;
if(q==0)
r=r->left;
else if(q->mData>p->mData)
q->left=p->left;
else
q->right=p->left;
delete p;
}
return true;
}
int main(int argc, char *argv[])
{
struct mNode *root=new struct mNode;
root->mData=23;
struct mNode *node1=new struct mNode;
node1->mData=12;
struct mNode *node2=new struct mNode;
node2->mData=15;
struct mNode *node3=new struct mNode;
node3->mData=28;
struct mNode *node4=new struct mNode;
node4->mData=30;
struct mNode *node5=new struct mNode;
node5->mData=35;
struct mNode *node6=new struct mNode;
node6->mData=40;
root->left=node2;
node2->left=node1; node2->right=0;
node1->left=0; node1->right=0;
root->right=node5;
node5->left=node3; node5->right=node6;
node3->left=0; node3->right=node4;
node4->left=0; node4->right=0;
node6->left=0; node6->right=0;
InOrder(root);
InsertElem(root,24);
InOrder(root);
printf("\n");
DeleteElem(root,28);
InOrder(root);
system("PAUSE");
return EXIT_SUCCESS;
}
三、图
对于图G=(V,E),可以用两种方法来表示,一种将图作为邻接链表的组合,另一种将图作为邻接矩阵来看待。
我们先用邻接矩阵来实现这张图:
struct Vertex
{
int mData;
bool mVisit;
};
struct Edge
{
int mV1;
int mV2;
};
struct Graph
{
Vertex mVertexSet[100];
int mVertexNum;
bool mMatrix[100][100];
};
void ResetVisit(Graph &G)
{
for(int i=0;i<G.mVertexNum;i++)
{
G.mVertexSet[i].mVisit=false;
}
}
void CreateGraph(Graph &G,Vertex V[],int Vnum,Edge E[],int Enum)
{
G.mVertexNum=Vnum;
for(int i=0;i<Vnum;i++)
{
G.mVertexSet[i]=V[i];
}
for(int i=0;i<Vnum;i++)
{
for(int j=0;j<Vnum;j++)
{
G.mMatrix[i][j]=false;
}
}
for(int i=0;i<Enum;i++)
{
G.mMatrix[E[i].mV1][E[i].mV2]=true;
}
}
int FirstAdjVertex(Graph &G,int v)
{
for(int i=0;i<G.mVertexNum;i++)
{
if(G.mMatrix[v][i])
return i;
}
return -1;
}
int NextAdjVertex(Graph &G,int v,int w)
{
for(int i=w+1;i<G.mVertexNum;i++)
{
if(G.mMatrix[v][i])
return i;
}
return -1;
}
因为需要进行BFS操作,我们又定义了一个队列:
struct MyQueue
{
int mSet[100];
int mHead;
int mTail;
int mLen;
};
void InitQueue(MyQueue &Q)
{
Q.mHead=0;
Q.mTail=0;
Q.mLen=0;
}
void EnQueue(MyQueue &Q,int item)
{
Q.mSet[Q.mTail]=item;
Q.mTail=(Q.mTail+1)%100;
Q.mLen++;
}
int DeQueue(MyQueue &Q)
{
int r=Q.mSet[Q.mHead];
Q.mHead=(Q.mHead+1)%100;
Q.mLen--;
return r;
}
bool IsEmptyQueue(MyQueue Q)
{
if(Q.mLen==0)
return true;
return false;
}
主函数如下:
#include <cstdlib>
#include <iostream>
#include "graph1.h"
#include "queue3.h"
using namespace std;
void DFS(Graph &G,int v)
{
printf("%d\t",G.mVertexSet[v].mData);
G.mVertexSet[v].mVisit=true;
for(int w=FirstAdjVertex(G,v);w!=-1;w=NextAdjVertex(G,v,w))
{
if(G.mVertexSet[w].mVisit==false)
DFS(G,w);
}
}
void BFS(Graph &G,int v)
{
MyQueue Q;
InitQueue(Q);
EnQueue(Q,v);
while(!IsEmptyQueue(Q))
{
int w=DeQueue(Q);
if(G.mVertexSet[w].mVisit==false)
{
printf("%d\t",G.mVertexSet[w].mData);
G.mVertexSet[w].mVisit=true;
}
for(int u=FirstAdjVertex(G,w);u!=-1;u=NextAdjVertex(G,w,u))
{
if(G.mVertexSet[u].mVisit==false)
EnQueue(Q,u);
}
}
}
int main(int argc, char *argv[])
{
Vertex VSet[6];
VSet[0].mData=0;VSet[1].mData=1;VSet[2].mData=2;
VSet[3].mData=3;VSet[4].mData=4;VSet[5].mData=5;
Edge ESet[16];
ESet[0].mV1=0;ESet[0].mV2=1; ESet[1].mV1=1;ESet[1].mV2=0;
ESet[2].mV1=0;ESet[2].mV2=2; ESet[3].mV1=2;ESet[3].mV2=0;
ESet[4].mV1=0;ESet[4].mV2=3; ESet[5].mV1=3;ESet[5].mV2=0;
ESet[6].mV1=0;ESet[6].mV2=4; ESet[7].mV1=4;ESet[7].mV2=0;
ESet[8].mV1=1;ESet[8].mV2=4; ESet[9].mV1=4;ESet[9].mV2=1;
ESet[10].mV1=2;ESet[10].mV2=4; ESet[11].mV1=4;ESet[11].mV2=2;
ESet[12].mV1=3;ESet[12].mV2=5; ESet[13].mV1=5;ESet[13].mV2=3;
ESet[14].mV1=4;ESet[14].mV2=5; ESet[15].mV1=5;ESet[15].mV2=4;
Graph G;
CreateGraph(G,VSet,6,ESet,16);
ResetVisit(G);
DFS(G,0);
printf("\n");
ResetVisit(G);
BFS(G,0);
system("PAUSE");
return EXIT_SUCCESS;
}
我们再用邻接表来实现上图:
#include <cstdlib>
#include <iostream>
#include "queue3.h"
using namespace std;
struct Edge
{
int index;
Edge *nextAdjEdge;
};
struct Vertex
{
int mData;
bool mVisit;
Edge *firstAdjEdge;
};
struct Graph
{
Vertex adjList[100];
int vertexNum;
int edgeNum;
};
void resetVisit(Graph &G)
{
for(int i=0;i<G.vertexNum;i++)
G.adjList[i].mVisit=false;
}
void createGraph(Graph &G,int vertexNum,Vertex v[],int edgeNum,Edge e[])
{
G.vertexNum=vertexNum;
G.edgeNum=edgeNum;
for(int i=0;i<vertexNum;i++)
{
G.adjList[i]=v[i];
}
}
int FirstAdjVertex(Graph G,int vertexNum)
{
if(G.adjList[vertexNum].firstAdjEdge!=NULL)
return G.adjList[vertexNum].firstAdjEdge->index;
return -1;
}
int NextAdjVertex(Graph G,int v,int w)
{
Edge *edge=G.adjList[v].firstAdjEdge;
while(edge->index!=w)
{
edge=edge->nextAdjEdge;
}
edge=edge->nextAdjEdge;
if(edge==NULL)
return -1;
return edge->index;
}
void DFS(Graph &G,int v)
{
printf("%d\t",G.adjList[v].mData);
G.adjList[v].mVisit=true;
for(int w=FirstAdjVertex(G,v);w!=-1;w=NextAdjVertex(G,v,w))
{
if(G.adjList[w].mVisit==false)
DFS(G,w);
}
}
void BFS(Graph &G,int v)
{
MyQueue Q;
InitQueue(Q);
EnQueue(Q,v);
while(!IsEmptyQueue(Q))
{
int w=DeQueue(Q);
if(G.adjList[w].mVisit==false)
{
printf("%d\t",G.adjList[w].mData);
G.adjList[w].mVisit=true;
}
for(int u=FirstAdjVertex(G,w);u!=-1;u=NextAdjVertex(G,w,u))
{
if(G.adjList[u].mVisit==false)
EnQueue(Q,u);
}
}
}
int main(int argc, char *argv[])
{
Graph G;
Edge E[16];
E[0].index=1;E[0].nextAdjEdge=&E[1];E[1].index=2;E[1].nextAdjEdge=&E[2];
E[2].index=3;E[2].nextAdjEdge=&E[3];E[3].index=4;E[3].nextAdjEdge=NULL;
E[4].index=0;E[4].nextAdjEdge=&E[5];E[5].index=4;E[5].nextAdjEdge=NULL;
E[6].index=0;E[6].nextAdjEdge=&E[7];E[7].index=4;E[7].nextAdjEdge=NULL;
E[8].index=0;E[8].nextAdjEdge=&E[9];E[9].index=5;E[9].nextAdjEdge=NULL;
E[10].index=0;E[10].nextAdjEdge=&E[11];E[11].index=1;E[11].nextAdjEdge=&E[12];
E[12].index=2;E[12].nextAdjEdge=&E[13];E[13].index=5;E[13].nextAdjEdge=NULL;
E[14].index=3;E[14].nextAdjEdge=&E[15];E[15].index=4;E[15].nextAdjEdge=NULL;
Vertex V[6];
V[0].mData=0; V[0].firstAdjEdge=&E[0];
V[1].mData=1; V[1].firstAdjEdge=&E[4];
V[2].mData=2; V[2].firstAdjEdge=&E[6];
V[3].mData=3; V[3].firstAdjEdge=&E[8];
V[4].mData=4; V[4].firstAdjEdge=&E[10];
V[5].mData=5; V[5].firstAdjEdge=&E[14];
createGraph(G,6,V,8,E);
resetVisit(G);
DFS(G,0);
printf("\n");
resetVisit(G);
BFS(G,0);
system("PAUSE");
return EXIT_SUCCESS;
}