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);
	}
}
相关推荐
pianmian11 小时前
python数据结构基础(7)
数据结构·算法
好奇龙猫3 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20244 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku4 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程4 小时前
双向链表专题
数据结构
香菜大丸4 小时前
链表的归并排序
数据结构·算法·链表
jrrz08284 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time4 小时前
golang学习2
算法
@小博的博客4 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生5 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法