树的实现 分级文件系统

数据结构与算法分析——c语言描述 第四章 树 分级文件系统


编程书有一个特点,就是看的时候觉得很简单,但是写代码就蒙了,各种出错,不停debug,想办法,重新写,再debug……是一个不停思考迭代的过程。因为原理大体简单,但是细节就麻烦得不得了。

模块化,分功能。就这样


几个有意思的地方,递归解析地址,递归遍历。


tree.h

typedef char* ElementType;


#ifndef _Tree_H
#define _Tree_H

struct TreeNode;
typedef struct TreeNode *PtrToNode;
typedef struct TreeNode *Tree;

Tree createTree();
void makeEmpty(Tree t);

void insert(char * address, char *filename, Tree t);
Tree del(ElementType x, Tree t);
void listDirectory(Tree t);
#endif


tree.c

#include"tree.h"
#include"fatal.h"
#include<string.h>
#define NAME_LENGTH 30

struct TreeNode {
	ElementType element;
	PtrToNode firstChild;//儿子
	PtrToNode nestSibling;//兄弟姐妹
};

static void delTreeNode(PtrToNode p) {//深度优先删除
	if (p != NULL)
	{
		PtrToNode child = p->firstChild;
		PtrToNode sibling = p->nestSibling;
		free(p->element);
		free(p);
		if (child)
			delTreeNode(child);
		if (sibling)
			delTreeNode(sibling);
	}
}

static PtrToNode addressToPtr(char * address, Tree t) {//广度优先搜索文件
	char *end = strchr(address, '/');
	int isLastName = 0;
	if (end == NULL)//当前调用的地址是最后一个
	{
		isLastName = 1;
		end = address;
		while (*end)
			end++;
	}
	char tempName[NAME_LENGTH];//为了用strcmp,所以复制了,其实自己写更好
	int cursor_tempname = 0;
	for (char *p = address; p != end; p++)
	{
		tempName[cursor_tempname++] = *p;
	}
	tempName[cursor_tempname] = '\0';


	PtrToNode Ptr_sameLevel = t;//搜索这一层的目录名字是否相同
	do
	{
		if (strcmp(Ptr_sameLevel->element, tempName) == 0)//相同
			break;
		Ptr_sameLevel = Ptr_sameLevel->nestSibling;//不相同,查下一个目录
	} while (Ptr_sameLevel);

	if (Ptr_sameLevel && isLastName)//找到了
		return Ptr_sameLevel;
	else if (Ptr_sameLevel && Ptr_sameLevel->firstChild && isLastName == 0)//islastname避免end+1溢出,否则如果是最后一个地址那么比出错
		return addressToPtr(end + 1, Ptr_sameLevel->firstChild);
	else
		Error("wrong address");
}

Tree createTree() {
	Tree t = malloc(sizeof(struct TreeNode));
	t->firstChild = NULL;
	t->nestSibling = NULL;
	t->element = malloc(sizeof(char)*NAME_LENGTH);
	strcpy(t->element, "usr");
	return t;
}



void makeEmpty(Tree t) {
	if (t != NULL)
	{
		delTreeNode(t->firstChild);
		t->firstChild = NULL;
		t->nestSibling = NULL;
		strcpy(t->element, "usr");
	}
}



void insert(char * address, char *filename, Tree t) {
	PtrToNode p = addressToPtr(address + 1, t);
	PtrToNode child = p->firstChild;

	PtrToNode newNode = malloc(sizeof(struct TreeNode));
	newNode->firstChild = NULL;
	newNode->nestSibling = NULL;
	newNode->element = malloc(sizeof(char)*NAME_LENGTH);
	strcpy(newNode->element, filename);

	if (child == NULL) {
		p->firstChild = newNode;
	}
	else {
		while (child->nestSibling)//其实也可以在第一个插入
			child = child->nestSibling;
		child->nestSibling = newNode;
	}
}

static printName(PtrToNode p, int depth) {
	while (depth--)
		printf("	");
	printf("%s\n", p->element);
}

static void listDir(Tree t, int depth) {
	if (t)
	{
		printName(t, depth);
		PtrToNode child = t->firstChild;
		while (child)
		{
			listDir(child, depth + 1);
			child = child->nestSibling;
		}
	}
}

void listDirectory(Tree t) {
	listDir(t, 0);
}


main.c

#include"tree.h"
#include<stdio.h>

struct TreeNode {
	ElementType element;
	PtrToNode firstChild;//儿子
	PtrToNode nestSibling;//兄弟姐妹
};

int main() {
	Tree t = createTree();
	insert("/usr", "aaa", t);
	
	insert("/usr", "bbb", t);
	
	insert("/usr", "ccc", t);

	insert("/usr/bbb", "ddd", t);

	listDirectory(t);

}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值