PTA目录树(使用字典树)

目录树

题目

在这里插入图片描述
在这里插入图片描述

答案

#include<iostream>
#include<algorithm>//使用sort函数
#include<cstring>//使用字符串相关函数
using namespace std;
//定义常量
const int N = 500;

//创建结构体
typedef struct node{
	char name[N];//名字
	int dir;//是否为目录,1是,0不是
	int num;//拥有的目录和文件总和
	struct node *next[N];//下一级
}Node,*Tree;

//自定义排序方式
bool cmp(Tree a,Tree b)
{
	if(a->dir!=b->dir) return a->dir>b->dir;//目录优先,文件靠后 
	else return strcmp(a->name,b->name)<0;	//级别相同,则按字典序排列 
} 

//类前序遍历
void pre_order(Tree root,int cnt)
{
	for(int i=0;i<cnt*2;i++)//循环输出空格 
	cout<<" ";
	cout<<root->name<<endl;
	
	sort(root->next,root->next+root->num,cmp);//排序 
	
	for(int i=0;i<root->num;i++)//向下一级进发 
	pre_order(root->next[i],cnt+1);	
} 

//主函数
int main()
{
	//定义相关变量
	int i,j,n,size; 
	
	//root初始化
	Tree root = new Node;
	strcpy(root->name,"root");
	root->dir=1;
	root->num=0;
	for(i=0;i<N;i++)
	root->next[i]=NULL;
	
	//输入总数n 
	cin>>n;
	while(n--)
	{
		//从根节点开始
		Tree p=root; 
		//定义两个字符数组
		char str[N],s[N];
		//输入字符串
		cin>>str;
		
		int k=0,len=strlen(str);
		for(i=0;i<len;i++)//遍历字符串 
		{
			if(str[i]!='\\') s[k++]=str[i];// '\' 要用 '\\' 来表示 
			else
			{
				s[k]='\0';//加上结束符
				size=p->num;
				for(j=0;j<size;j++)//遍历寻找该目录是否已经存在 
				if(strcmp(p->next[j]->name,s)==0)
				{
					p=p->next[j];
					break;
				}
				if(j==size)//如果不存在 
				{
					size=p->num;
					p->next[size]=new Node;//创建新节点
					strcpy(p->next[size]->name,s);
					p->next[size]->dir=1;
					p->next[size]->num=0;
					p->num+=1;
					p=p->next[size];
				}	
				k=0;//k还原为0 
			}	
		}
		if(str[len-1]!='\\')//如果最后一个是文件 
		{
			s[k]='\0';
			size=p->num;
			p->next[size]=new Node;//创建新节点
			strcpy(p->next[size]->name,s);
			p->next[size]->dir=0;
			p->next[size]->num=0;
			p->num++;
		}	
	}	
	pre_order(root,0);//遍历打印结果 
} 

总结

本题的思路是采用字典树解题,我个人对于字典树的理解就是在链表的基础上,将next扩展为数组,以实现1对多的目的

本题我参考了这篇文章——目录树 PTA,注释方面进行了个性化的修改

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值