[Algorithms]二叉树遍历方法与代码实现

[Algorithms]二叉树、图遍历方法与代码实现

1. 二叉树遍历方法

首先,是本文使用二叉树结构的一个声明。

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
一、前序遍历

原理:若二叉树为空,则空操作返回,否则先访问根节点,然后前序遍历左子树,再前序遍历右子树。

[Algorithms]二叉树遍历方法与代码实现

/* 前序遍历递归 */
void PreOrderTraverse(BiTree T)
{
	if(T==NULL)
		return;
	printf("%c",T->data);
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
}
二、中序遍历

原理:若二叉树为空,则空操作返回,否则从根节点开始(注意并不是先访问根节点),中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树。

[Algorithms]二叉树遍历方法与代码实现

/* 中序遍历递归 */
void InOrderTraverse(BiTree T)
{
	if(T==NULL)
		return;
	InOrderTraverse(T->lchild);
	printf("%c",T->data);
	InOrderTraverse(T->rchild);
}
三、后序遍历

原理:若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后访问根结点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMqimKvN-1645500271630)(https://lkk2lqq.com/picture/后序遍历.png)]

/* 后序遍历递归 */
void PostOrderTraverse(BiTree T)
{
	if(T==NULL)
		return;
	PostOrderTraverse(T->lchild);
	PostOrderTraverse(T->rchild);
	printf("%c",T->data);
}
四、层序遍历

原理:若树为空,则空操作返回,否则从树的第一层,也就是根节点开始访问,从上而下逐层遍历,在同一层中,从左到右的顺序对结点逐个访问。

[Algorithms]二叉树遍历方法与代码实现

2. 图遍历方法

一、 深度优先遍历(DFS)
  1. 邻接矩阵的遍历算法
/* 图的声明->邻接矩阵方式:可能内存的使用率低 */
#define MAXVEX 100
#define INFINITY 65535
typedef struct
{
    
	char vexs[MAXVEX]; /*顶点表*/
    int arc[MAXVEX][MAXVEX]; /*邻接矩阵,可看做边表*/
    int numVertexes,numEdges; /*图中当前的顶点数和边数*/
}MGraph;


bool visited[MAX];
/* 邻接矩阵的深度优先递归算法 */
void DFS(MGraph G,int i)
{
    int j;
    visited[i]=true;
    printf("%c",G.vexs[i]);
    for(j=0;j<G.numVertexes;j++)
    {
        if(G.arc[i][j] == 1 && !visited[j])
        {
            DFS(G,j);
        }
    }
}
/* 邻接矩阵的深度遍历操作 */
void DFSTraverse(MGraph G)
{
    int i;
    for(i = 0;i < G.numVertexes;i++ )
    {
        visited[i] = false;
    }
    for(i = 0;i < G.numVertexes;i++)
    {
        if(!visited[i])
            DFS(G,i);
    }
}
  1. 邻接表的遍历算法
/* 图的声明->邻接表方式:链式存储,结构复杂 */
typedef struct EdgeNode /*边表结点*/
{
    int adjvex;
    int weight; /*权值非网图可以不需要*/
    struct EdgeNode *next;/*链域指向下一个邻接点*/
}EdgeNode;

typedef struct VertexNode /*顶点表结点*/
{
    int data;/*顶点域*/
    EdgeNode *firstedge;/*边表头指针*/
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes,numEdges; /*图中当前顶点数和边数*/
}GraphAdjList;

/* 邻接表的深度优先递归算法 */
void DFS(GraphAdjList GL,int i)
{
    EdgeNode *p;
    visited[i]=true;
    printf("%c",GL->adjlist[i].data);
    while(p)
    {
        if(!visited[p->adjvex])/*如果没走过这条路,那就走到下一个顶点*/
            DFS(GL,p->adjvex);
        p = p->next;
    }
}
/* 邻接表的深度遍历操作 */
void DFSTraverse(MGraph G)
{
    int i;
    for(i = 0;i < GL->numVertexes;i++ )
    {
        visited[i] = false;
    }
    for(i = 0;i < G->numVertexes;i++)
    {
        if(!visited[i])
            DFS(GL,i);
    }
}
二、 广度优先遍历(BFS)
  1. 邻接矩阵的广度遍历算法

为了方便,直接把前文提到的声明放到这里,比较直观。

/* 图的声明->邻接矩阵方式:可能内存的使用率低 */
#define MAXVEX 100
#define INFINITY 65535
typedef struct
{
    
	char vexs[MAXVEX]; /*顶点表*/
    int arc[MAXVEX][MAXVEX]; /*邻接矩阵,可看做边表*/
    int numVertexes,numEdges; /*图中当前的顶点数和边数*/
}MGraph;

/*邻接矩阵的广度遍历算法*/
void BFSTraverse(MGraph G)
{
    int i,j;
    Queue Q;
    for(i = 0;i < G.numVertexes; i++)
    {
        visited[i] = false;
    }
    InitQueue(&Q);/*初始化辅助队列*/
    for(i = 0;i < G.numVertexes; i++)
    {
        if(!visited[i])
        {
            visited[i]=true;
            printf("%c",G.vexs[i]);
            EnQueue(&Q,i);
            while(!QueueEmpty(Q))
            {
                DeQueue(&Q,&i); /* 将队中元素出队列,赋值给i */
            	for(j = 0;j < G.numVertexes; j++)
                {
                    /* 若其他顶点与当前顶点存在边且未访问过 */
                    if(G.arc[i][j] == 1 && !visited[j])
                    {
                        visited[j]=true;
                        printf("%c",G.vexs[j]);
                        EnQueue(&Q,j);
                    }
                }
            }
            
        }
    }
}


  1. 邻接表的广度遍历算法
/* 图的声明->邻接表方式:链式存储,结构复杂 */
typedef struct EdgeNode /*边表结点*/
{
    int adjvex;
    int weight; /*权值非网图可以不需要*/
    struct EdgeNode *next;/*链域指向下一个邻接点*/
}EdgeNode;

typedef struct VertexNode /*顶点表结点*/
{
    int data;/*顶点域*/
    EdgeNode *firstedge;/*边表头指针*/
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes,numEdges; /*图中当前顶点数和边数*/
}GraphAdjList;

void BFSTraverse(GraphAdjList GL)
{
    int i;
    EdgeNode *p;
    Queue Q;
    for(i = 0; i < GL->numVertexes; i++)
    {
        visited[i]=false;
    }
    InitQueue(&Q);
    for(i = 0 ; i < GL->numVertexes; i++)
    {
        if(!visited[i])
        {
            visited[i] = true;
            printf("%c",GL->adjList[i].data);
            EnQueue(&Q,i);
            while(!QueueEmpty(Q))
            {
                DeQueue(&Q,&i);
                /*以下代码参考邻接矩阵的话很好理解*/
                p = GL->adjList[i].firstedge; /*找到当前顶点边表链表头指针*/
                while(p)
                {
                    if(!visited[p->adjvex])
                    {
                        visited[p->adjvex] = true;
                        printf("%c",GL->adjList[p->adjvex].data);
                        EnQueue(&Q,p->adjvex);
                    }
                    p = p->next;
                }
            }
        }
    }
}
上一篇:docker 安装镜像-----mysql


下一篇:基于CentOS快速搭建LNMP环境【分布搭建】