3.21Code

基于二叉链表的二叉树最大宽度的计算

cpp 复制代码
#include<iostream>

#define MAXSIZE 1000

using namespace std;


int k=0;
int m=0; //记录层数 

typedef struct BiNode{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
}BiNode,*BiTree;

void CreateBiTree(BiTree &T){
	char ch;
	cin>>ch;
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		m++; 
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 		
	}
}

void CreateBiTree(BiTree &T,char ch){
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		m++;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 
	}
}

void Traverse(BiTree T,int n[]){
	if(T){
		//k代表当前遍历到的层数! 
		k++;
		n[k]++;
		Traverse(T->lchild,n);
		Traverse(T->rchild,n);
		k--;
	}
}

void Width(int n[]){
	int max=n[1];
	for(int i=2;i<=m;i++)
		if(max<n[i])max=n[i];
	cout<<max<<endl;
} 

int main(){
	while(true){
		char ch;
		int n[100]={0};
		cin>>ch;
		if(ch=='0')break;
		BiTree T;
		CreateBiTree(T,ch);
		Traverse(T,n);
		Width(n);		
	}
	return 0;
} 

【思路】每创建一个结点,m++,m维护节点数。

遍历的时候,每进入一层,k++,n[k]++,k维护层数。注意在找完左右子树时,要k--,方便向上层递归

n[i]代表第i个结点对应层的结点个数

最后遍历n数组,找到最大值即可

基于二叉链表的二叉树叶子结点到根结点的路径的求解

cpp 复制代码
#include<iostream>

#define MAXSIZE 1000

using namespace std;


int maxi=0;
int m=0,n=0;

typedef struct BiNode{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
}BiNode,*BiTree;


void CreateBiTree(BiTree &T){
	char ch;
	cin>>ch;
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		m++; 
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 		
	}
}

void CreateBiTree(BiTree &T,char ch){
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		m++;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 
	}
}

void Traverse(BiTree T){
	if(T){
		m++;
		Traverse(T->lchild);
		Traverse(T->rchild);
		m--;
	}
}

void FindRoad(BiTree T,char path[],int pathlen){
	if(T){
		if(T->lchild==NULL && T->rchild==NULL){
			//叶子节点
			cout<<T->data;
			for(int i=pathlen-1;i>=0;i--) 
				cout<<path[i];
			cout<<endl;
		}
		else{
			path[pathlen]=T->data;
			pathlen++;
			FindRoad(T->lchild,path,pathlen);
			FindRoad(T->rchild,path,pathlen);
			pathlen--; //很重要 
		}
	}
}

int main(){
	while(true){
		char ch;
		cin>>ch;
		char path[100];
		int pathlen=0;
		if(ch=='0')break;
		BiTree T;
		CreateBiTree(T,ch);	
		Traverse(T);
		FindRoad(T,path,pathlen);
		m=0;
	}
	return 0;
} 

【思路】重点在于FindRoad函数,参数是path数组和当前path数组应储存的下标

遇到叶子结点时输出整个数组内容,否则存入当前结点名称,进入左右孩子的递归

由以上两题,注意形参是数组时,可以写成int n[ ]的形式

基于二叉链表的二叉树的遍历

cpp 复制代码
#include<iostream>

#define MAXSIZE 1000

using namespace std;


typedef struct BiNode{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
}BiNode,*BiTree;


void CreateBiTree(BiTree &T){
	char ch;
	cin>>ch;
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 		
	}
}

void CreateBiTree(BiTree &T,char ch){
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 
	}
}

void PreTraverse(BiTree T){
	if(T){
		cout<<T->data;
		PreTraverse(T->lchild);
		PreTraverse(T->rchild);
	}
}

void MidTraverse(BiTree T){
	if(T){

		MidTraverse(T->lchild);
		cout<<T->data;
		MidTraverse(T->rchild);
	}
}

void LastTraverse(BiTree T){
	if(T){
		LastTraverse(T->lchild);
		LastTraverse(T->rchild);
		cout<<T->data;
	}
}


int main(){
	while(true){
		char ch;
		cin>>ch;
		char path[100];
		int pathlen=0;
		if(ch=='0')break;
		BiTree T;
		CreateBiTree(T,ch);	
		PreTraverse(T);cout<<endl;
		MidTraverse(T);cout<<endl;
		LastTraverse(T);cout<<endl;
	}
	return 0;
} 

基于二叉链表的二叉树结点个数的统计

cpp 复制代码
#include<iostream>

#define MAXSIZE 1000

using namespace std;

int n0=0,n1=0,n2=0;

typedef struct BiNode{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
}BiNode,*BiTree;


void CreateBiTree(BiTree &T){
	char ch;
	cin>>ch;
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 		
	}
}

void CreateBiTree(BiTree &T,char ch){
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 
	}
}

void PreTraverse(BiTree T){
	if(T){
		if(T->lchild && T->rchild)n2++;
		else if(T->lchild && !T->rchild)n1++;
		else if(!T->lchild && T->rchild)n1++;
		else n0++;
		PreTraverse(T->lchild);
		PreTraverse(T->rchild);
	}
}

void MidTraverse(BiTree T){
	if(T){

		MidTraverse(T->lchild);
		cout<<T->data;
		MidTraverse(T->rchild);
	}
}

void LastTraverse(BiTree T){
	if(T){
		LastTraverse(T->lchild);
		LastTraverse(T->rchild);
		cout<<T->data;
	}
}


int main(){
	while(true){
		char ch;
		cin>>ch;
		char path[100];
		int pathlen=0;
		if(ch=='0')break;
		BiTree T;
		CreateBiTree(T,ch);	
		PreTraverse(T);
		cout<<n0<<" "<<n1<<" "<<n2<<endl;
		n0=n1=n2=0;
	}
	return 0;
} 

基于二叉链表的二叉树高度的计算

cpp 复制代码
#include<iostream>

#define MAXSIZE 1000

using namespace std;

int maxd=0;
typedef struct BiNode{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
}BiNode,*BiTree;


void CreateBiTree(BiTree &T){
	char ch;
	cin>>ch;
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 		
	}
}

void CreateBiTree(BiTree &T,char ch){
	if(ch=='0')T=NULL;
	else{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild); 
	}
}

void PreTraverse(BiTree T,int &nowd){
	if(T){
		nowd++;
		maxd=max(nowd,maxd);
		PreTraverse(T->lchild,nowd);
		PreTraverse(T->rchild,nowd);
		nowd--;
	}
}

void MidTraverse(BiTree T){
	if(T){

		MidTraverse(T->lchild);
		cout<<T->data;
		MidTraverse(T->rchild);
	}
}

void LastTraverse(BiTree T){
	if(T){
		LastTraverse(T->lchild);
		LastTraverse(T->rchild);
		cout<<T->data;
	}
}


int main(){
	while(true){
		char ch;
		cin>>ch;
		char path[100];
		int pathlen=0;
		if(ch=='0')break;
		BiTree T;
		CreateBiTree(T,ch);	
		int d=0;	
		PreTraverse(T,d);
		cout<<maxd<<endl;
		maxd=0;
	}
	return 0;
} 

【注意】最大高度应该用一个全局变量来维护,而每次遍历到的深度则用临时变量来存储和递归传参,在递归前nowd++了,在这一层最终还要nowd--,以便向上回溯!

------------------------------------华丽的分界线------------------------------------------------

------------------------以下是图及应用相关习题------------------------------------------------

基于Dijsktra算法的最短路径求解

【Dijkstra算法】

cpp 复制代码
#include <iostream>
#include <cstring>
#define MVNum 100
#define MaxInt 999
using namespace std;
 
typedef struct
{
	char vexs[MVNum];//点集 
	int arcs[MVNum][MVNum];//边的邻接矩阵 
	int vexnum,arcnum;//点数&边数 
}AMGraph;
 
int LocateVex(AMGraph G,char u)
 {//存在则返回u在顶点表中的下标;否则返回-1
   int i;
   for(i=0;i<G.vexnum;++i)
     if(u==G.vexs[i])
       return i;
   return -1;
 }
 
void InitAM(AMGraph &G)
{//初始化图 
 	memset(G.vexs,0,sizeof(G.vexs));//初始化顶点集 
	for(int i=0;i<MVNum;i++)
		for(int j=0;j<MVNum;j++)
			G.arcs[i][j]=MaxInt;
	return;
}
 
void CreateUDN(AMGraph &G)
{
	int i,j,k;  
	//G.vexnum++;
	for(i=0;i<G.vexnum;i++)
		cin>>G.vexs[i];
	for(k=0;k<G.arcnum;k++)//将边录入邻接矩阵,顺便将顶点录入 
	{
		char v1,v2;int w;
		cin>>v1>>v2>>w;//边的端点
		i=LocateVex(G,v1);
		j=LocateVex(G,v2);
		G.arcs[i][j]=w;
		G.arcs[j][i]=G.arcs[i][j];
		G.arcs[i][j]=w;
		G.arcs[k][k]=0;
	}
}
 
void ShortestPath_DIJ(AMGraph G){ 
    //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径 
    char v0,v1;
    int S[MVNum];
    int D[MVNum];
    int Path[MVNum];
    cin>>v0>>v1;
    int v00=LocateVex(G,v0);
    int n=G.vexnum; int v;                  		//n为G中顶点的个数 
    for( v = 0; v<n; ++v){             	//n个顶点依次初始化 
       S[v] = false;                  	//S初始为空集 
       D[v] = G.arcs[v00][v];           	//将v0到各个终点的最短路径长度初始化 
       if(D[v]< MaxInt)  Path [v]=v00; //v0和v之间有弧,将v的前驱置为v0 
       else Path [v]=-1;               	//如果v0和v之间无弧,则将v的前驱置为-1 
      }//for 
      S[v00]=true;                    	//将v0加入S 
      D[v00]=0;     
	  int w;  int i;               		//源点到源点的距离为0 	
/*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/ 
      for(i=1;i<n; ++i){               	//对其余n?1个顶点,依次进行计算 
        int min= MaxInt;  
        for(w=0;w<n; ++w) 
          if(!S[w]&&D[w]<min)  
              {v=w; min=D[w];}         	//选择一条当前的最短路径,终点为v 
        S[v]=true;                   		//将v加入S 
        for(w=0;w<n; ++w) 	//更新从v0出发到集合V?S上所有顶点的最短路径长度 
        if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){ 
             D[w]=D[v]+G.arcs[v][w];   	//更新D[w] 
             Path [w]=v;              		//更改w的前驱为v 
        }//if 
    }//for   
	w=LocateVex(G,v1);
	cout<<D[w]<<endl; 
	char road[G.vexnum];
	road[0]=G.vexs[w];
	int t=w;i=0;
	while(1)
	{  
		i++;
		if(t==-1||t==v00)break;
		road[i]=G.vexs[Path[t]];
		t=Path[t];	
	}
	while(i)
	{
		if(road[i])cout<<road[i]<<" ";
		i--;
	} 
	cout<<road[0];
	cout<<endl;
}
 
 
int main()
{	
	while(1)
	{
		AMGraph G;
		InitAM(G);
		cin>>G.vexnum>>G.arcnum;
		if(G.vexnum==0&&G.arcnum==0)break;
		CreateUDN(G);
		ShortestPath_DIJ(G);
	}
}
相关推荐
一杯咖啡Miracle3 分钟前
UV管理python环境,打包项目为docker流程
python·算法·docker·容器·uv
玉树临风ives9 分钟前
atcoder ABC438 题解
数据结构·算法
算法与编程之美17 分钟前
探索不同的损失函数对分类精度的影响
人工智能·算法·机器学习·分类·数据挖掘
MSTcheng.21 分钟前
【C++】平衡树优化实战:如何手搓一棵查找更快的 AVL 树?
开发语言·数据结构·c++·avl
-Excalibur-22 分钟前
ARP RIP OSPF BGP DHCP以及其他计算机网络当中的通信过程和广播帧单播帧的整理
c语言·网络·python·学习·tcp/ip·算法·智能路由器
刃神太酷啦22 分钟前
Linux 底层核心精讲:环境变量、命令行参数与程序地址空间全解析----《Hello Linux!》(7)
linux·运维·服务器·c语言·c++·chrome·算法
前端小L24 分钟前
贪心算法专题(五):覆盖范围的艺术——「跳跃游戏」
数据结构·算法·游戏·贪心算法
前端小L25 分钟前
贪心算法专题(六):步步为营的极速狂飙——「跳跃游戏 II」
算法·游戏·贪心算法
谈笑也风生29 分钟前
经典算法题型之排序算法(一)
算法·排序算法
叫我:松哥36 分钟前
基于django的新能源汽车租赁推荐分析系统,包括用户、商家、管理员三个角色,协同过滤+基于内容、用户画像的融合算法推荐
python·算法·机器学习·pycharm·django·汽车·echarts