[英]How to sort tree of folders
我有一疊平面樹。 該樹具有以下屬性:id,parent_id,name。
我將這棵樹存儲在一個簡單的數組中。 問題是該數組未排序。
我數組的一個元素是這樣的簡單對象:
var obj = { id: 1, parent_id: null, name: "Folder" }
我想對它進行排序,以便能夠看到類似以下內容的東西:
Folder1
Sub_folder1
Sub_sub_folder1
Sub_folder2
Sub_sub_folder2
所以,一個...我不想使用遞歸,也不知道如何正確地做。
這是我的一些嘗試。 我嘗試在id中添加一個人工字段,該字段將代表集合中每個文件夾的數量,但是它不起作用。
var sort = function(list) {
var f_map = {};
var sorting_index = 1;
var tree = angular.copy(list);
for(var i = 0; i < tree.length; i++) {
var node = tree[i];
f_map[ node.id ]= { index: i, children: [] };
if (node.parent_id) {
f_map[ node.parent_id ].children.push( node.id );
};
var idx = 0;
var visited = {};
for(var key in f_map) {
var index = f_map[key].index;
var node = tree[index];
if (!visited[node.id]) {
node.nuid = idx++;
} else {
visited[node.id] = true;
};
if (f_map[key].children.length) {
var children = f_map[key].children;
for(var i = 0; i < children.length; i++) {
var child_id = children[i];
var child_idx = f_map[child_id].index;
var child = tree[child_idx];
child.nuid = idx++;
visited[child.id] = true;
};
};
};
tree.sort(function(left, right) {
return left.nuid - right.nuid;
});
return tree;
};
由於您將父指針表示為對父節點id
的引用,因此我首先將文件夾的表示形式更改為對象表示形式:
var folders = {
1: {parent_id: null, name: "Folder", path: null},
...
};
我添加了一個path
字段,以便可以記住以下遞歸函數的結果以查找文件夾的完整路徑:
function path(node) {
if (node.path !== null) return node.path;
if (node.parent_id === null) {
node.path = '/' + node.name;
} else {
node.path = path(folders[node.parent_id]) + '/' + node.name;
}
return node.path;
}
然后,我們可以通過首先提取要排序的字段和對該項目的引用來進行Schwartzian變換:
var keys = [];
Object.keys(folders).map(function (key) {
var folder = folders[key];
keys.push({path: path(folder), id: key});
});
然后我們可以對keys數組進行排序:
keys.sort(function (a, b) {
var apath = a.path;
var bpath = b.path;
// probably the best way to compare folder paths..
return apath.localeCompare(bpath);
});
最后,我們可以遍歷keys數組來按排序順序生成文件夾:
var sorted_folders = keys.map(function (item) {
return folders[item.id]; // .name; or maybe .path; ??
});
就像sorted_folders
是文件夾對象的列表一樣,但是根據注釋,您可以在此步驟中輕松提取所需的屬性。
首先,遞歸並不慢。 這是在您的武器庫中使用的好工具。 它使解決某些問題變得容易得多。
這是應該解決的算法。
1. If the graph can be a forest and not a tree
create a new node root
Make all roots in forest point to this root as parent
2. For every node, create an array (stack) of its children, call it c[i].
3. For each vertex v in tree
c[v.parent].push(v)
4. u = root, i = 0
5. print u
6. while c[root] is not empty and u != root
if c[u] is not empty
u = pop(c[u])
i++
print tab i times
print u
if c[u] is empty and u != root
u = u.parent
i--
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.