基本数据结构之树、图

来源:互联网 发布:笑气淘宝怎么买 编辑:程序博客网 时间:2024/06/06 18:00

一、二叉树

这里写图片描述
以下采用链表结构来实现上图的二叉树:

#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;}
原创粉丝点击