美文网首页leetcode刷题
文件树整理与排序

文件树整理与排序

作者: 小丸子啦啦啦呀 | 来源:发表于2018-05-02 07:58 被阅读0次

话不多说,先来个华丽的对比图:


对比图

左边乱糟糟,右边看起来舒服多了。
排序规则:

  1. 文件夹在前,文件在后
  2. 名字从第一个字符开始比较,数字在前,字母在后;如果是同一字母(A与a),大写在前,小写在后。
  3. 如果遇到非字母,数字,统一放到最后。(其实新建文件夹和文件的时候就做了数据验证,不允许输入数字和字母意外的字符作为名字,但是为了保险起见,还是做一下处理)。

数据输入格式:

const treeData = {
    name: "root",
    type: "folder", // 文件还是文件夹
    children: [{
        name: 'b', // 名字
        type: 'folder',
        children: [{ 
            name: 'f',
            type: 'file',
        }, {
            name: 'F',
            type: 'folder',
        }]
    }, {
        name: 'c', 
        type: 'file',
    }, {
        name: 'a',
        type: 'file',
    }, {
        name: 'B',
        type: 'fold'
    }, {
        name: 'A',
        type: 'fold',
    }, {
        name: 'd',
        type: 'file',
    }, {
        name: 'e',
        type: 'file',
    }, {
        name: 'E',
        type: 'fold',
    }, {
        name: '510',
        type: 'folder',
        children: [{
            name: '3',
            type: 'file',}
        ]
    }, {
        name: '234',
        type: 'folder',
    }],
}

步骤

  1. 假设有一个process方法,该方法可以对一个树节点的所有孩子进行排序处理,那么如果需要排好整棵树,就遍历一下这棵树,对每个树节点调用process方法。
const traverse = (node) => {
  if (node.children && node.children.length) {
    node.children = process(node.children);
    node.children.forEach((element) => {
      traverse(element);
    });
  }
};
  1. process的具体实现:首先把文件夹和文件分别放到不同的列表里,然后再分别对这两个列表进行首字母ascii码排序,完成后分别对这两个列表做大小写处理,最后将这两个列表拼接起来返回。
function process(children) {
  if (children.length <= 1) return children;
  // 把文件夹和文件分开:文件夹在前,文件在后
  let foldList = [];
  let fileList = [];
  for (let i = 0; i < children.length; i += 1) {
    const node = children[i];
    if (node.type === 'folder') {
      foldList.push(node);
    } else if (node.type === 'file') {
      fileList.push(node);
    }
  }
  // 按照首字母ascii码排序
  bubbleSort(foldList);
  bubbleSort(fileList);

  // 处理大小写
  foldList = proceeBS(foldList);
  fileList = proceeBS(fileList);
  // console.log('----fold', foldList);
  // console.log('----file', fileList);
  return foldList.concat(fileList);
}
  1. bubbleSort实现方法,用到了charCodeAt
/**
 * 首字符排序
 * @param {*} list
 * a c B A 1 3 -> 1 3 A B a c
 */
function bubbleSort(list) {
  for (let i = 0; i < list.length; i += 1) {
    for (let j = 0; j < list.length - 1 - i; j += 1) {
      if (list[j].name.charCodeAt(0) > list[j + 1].name.charCodeAt(0)) {
        const temp = list[j];
        list[j] = list[j + 1];
        list[j + 1] = temp;
      }
    }
  }
  return list;
}
  1. 处理大小写proceeBS方法实现:
/**
 * 找出大写和小写字母开头的分界点
 * @param {*} list
 * A B E c d e -> 3
 */
const getPivot = (list) => {
  for (let i = 0; i < list.length - 1; i += 1) {
    const charCode = list[i].name.charCodeAt(0);
    if (charCode < 97 && charCode >= 65) {
      const nextCharCode = list[i + 1].name.charCodeAt(0);
      if (nextCharCode >= 97 && nextCharCode <= 122) {
        return i + 1;
      }
    }
  }
  return null;
};
/**
 * 处理大小写排序
 * @param {*} list
 * A B E a e -> A a B E e
 */
function proceeBS(list) {
  // 找出大小写分界位置
  const pivot = getPivot(list);
  // 如果没有分界位置,说明全部都是大写或者小写,没有必要再做处理
  if (pivot === null) return list;
  // console.log('-----pivot', pivot);
  //  放置排好的元素 
  let mergeList = [];
  // 大写字母列表
  const bigList = list.slice(0, pivot);
  //  小写字母列表
  const smallList = list.slice(pivot, list.length);
  // console.log('-----big', bigList);
  // console.log('-----small', smallList);
  let i = 0;
  let j = 0;
  while (i < bigList.length && j < smallList.length) {
    const bigCharCode = bigList[i].name.charCodeAt(0);
    const smallCharCode = smallList[j].name.charCodeAt(0);
    // 刚好相差32  说明是一对儿
    if (smallCharCode - bigCharCode === 32) {
      mergeList.push(bigList[i]);
      mergeList.push(smallList[j]);
      i += 1;
      j += 1;
    } else if (smallCharCode - bigCharCode > 32) {
      mergeList.push(bigList[i]);
      i += 1;
    } else {
      // <32的情况
      mergeList.push(smallList[j]);
      j += 1;
    }
  }
  // console.log('----mergelist before', mergeList, i, j);
  // 看谁还没走完
  // console.log('----i,j', i, j);
  if (i < bigList.length) {
    mergeList = mergeList.concat(bigList.slice(i, bigList.length));
  }
  if (j < smallList.length) {
    mergeList = mergeList.concat(smallList.slice(j, smallList.length));
  }
  // console.log('----mergelist after', mergeList);
  return mergeList;
}

改进

  1. 排序的时候只考虑了首字母,如果首字母一样该怎么处理呢?那就继续取出下一个字符再比较,直到某个字符串没有字符可取为止。
/**
 * 按位比较字符串 abx abs -> true
 * @param {*} strA
 * @param {*} strB
 * strA 比 strB 大的时候返回true
 */
function compare(strA, strB) {
  // eslint-disable-next-line
  // debugger;
  let i = 0;
  let j = 0;
  while (i < strA.length && j < strB.length) {
    const aCharCode = strA.charCodeAt(i);
    const bCharCode = strB.charCodeAt(j);
    if (aCharCode > bCharCode) return true;
    if (aCharCode === bCharCode) {
      i += 1;
      j += 1;
    }
    if (aCharCode < bCharCode) return false;
  }
  if (i < strA.length) return true;
  return false;
}
  1. 咨询算法小伙伴,他认为在做排序和大小写处理的时候,其实总到了每个节点的name, 所以没有必要带上整个节点进行排序,可以做一个mapping, 排好之后再mapping 回去。

引申

数据处理放前端做还是放后端做?
这个问题我迷惑了好一阵了,有时候从接口取出来的数据并不能直接应用到视图上,需要做一些处理。那什么时候放前端处理比较合适呢?
我想了想,如果一套数据为了适应不同的视图需要转换成不同的格式,那么放在前端做比较合适,因为不这样做的话,每次都要重新从后端取出来,这样做 不划算。
随后我问了一下师傅,师傅说首先考虑一下数据量大小和复杂程度,如果量大,处理起来复杂,那还是放后端做,其次可以考虑我说的那一点,有道理。

相关文章

  • 文件树整理与排序

    话不多说,先来个华丽的对比图: 左边乱糟糟,右边看起来舒服多了。排序规则: 文件夹在前,文件在后 名字从第一个字符...

  • 常用四种排序算法的思想与实现

    无整理 不简书 常用的排序算法有冒泡排序、选择排序、插入排序、快速排序,下面简单介绍四种排序方法的思路与实现代码。...

  • 《算法笔记》4.1

    4.1.1选择排序 4.1.2插入排序 4.1.3排序题与sort函数的应用 6.9.6关于sort函数 头文件 ...

  • 说说如何使用 Python 遍历目录树

    假设有这样一个任务,希望对某个文件夹(包括所有子文件夹与文件)中的所有文件进行处理。这就需要遍历整理目录树, 处理...

  • Xcode 使用小Tips

    1 Xcode文件 .h .m排序很乱,想一键整理 步骤如下:选中文件夹,右键Sort by Name。只能单个文...

  • xcode .m .h 文件排序错乱

    选中要整理的文件夹右键,点一下“Sort by Name”或者“Sort by Type”即可排序。

  • 比较器 二叉树实现(BinaryTree)

    与链表不同的是,树的最大特征是可以针对数据进行排序。(二叉排序树) 二叉排序树的操作原理选择第一个数据作为根节点,...

  • 八大排序算法

    排序分类:内部排序、外部排序 外部排序 大文件的排序,即待排序的记录存储在[外存储器]26993)上,待排序的文件...

  • ios 拖进工程中的文件顺序错乱

    在工程中选中要整理的文件夹,右键,点击“Sort by Name”或者“Sort by Type”即可排序。Sor...

  • java归并排序

    概述 归并排序与快速排序相同,同样是借鉴二叉树的思想,时间复杂度O(n),与快速排序一样是大量数据排序的最优方式之...

网友评论

    本文标题:文件树整理与排序

    本文链接:https://www.haomeiwen.com/subject/ahefrftx.html