如何编写一个函数来浏览非二叉树?

问题描述 投票:0回答:1

我有一个使用“react-organizational-chart”npm 包在 React/Nextjs 中构建的公司组织结构图。

我希望用户能够使用键盘键、屏幕按钮或两者在非二叉树上向上/向下和左右导航。

例如,用户可能会从“Sarah”->“Michael”->“Robert”->“Emily”->“Daniel”-“Sophie”

请参阅下图以了解视觉表现。

当移动到新的节点组时,用户总是希望从该组中的第一个节点开始。

这是屏幕截图中呈现的数据示例。

用户还可以回到树上并从另一侧下来。

从“Sarah”5555 开始该函数应如何工作的表示

navigateHierarchy('downKey') // 5556 (Michael Davis's id )
navigateHierarchy('rightKey') // 5560 (Robert Smith's id )
navigateHierarchy('downKey') // 5561 (Emily Wilson's id )
navigateHierarchy('rightKey') // 5561 (Daniel Brown's id )
navigateHierarchy('rightKey') // 5563 (Daniel Brown's id )
const data: IHierarchyData = [
  {
    name: "Sarah Johnson",
    position: "CEO",
    email: "[email protected]",
    id: "5555",
    children: [
      {
        name: "Michael Davis",
        position: "CFO",
        email: "[email protected]",
        id: "5556",
        children: [
          {
            name: "Sophia Adams",
            position: "Finance Manager",
            email: "[email protected]",
            id: "5557",
            children: [],
          },
          {
            name: "William Harris",
            position: "Financial Analyst",
            email: "[email protected]",
            id: "5558",
            children: [],
          },
          {
            name: "Oliver Turner",
            position: "Accounting Manager",
            email: "[email protected]",
            id: "5559",
            children: [],
          },
        ],
      },
      {
        name: "Robert Smith",
        position: "COO",
        email: "[email protected]",
        id: "5560",
        children: [
          {
            name: "Emily Wilson",
            position: "VP of Operations",
            email: "[email protected]",
            id: "5561",
            children: [],
          },
          {
            name: "Daniel Brown",
            position: "Director of Production",
            email: "[email protected]",
            id: "5562",
            children: [],
          },
          {
            name: "Sophie Turner",
            position: "Director of Logistics",
            email: "[email protected]",
            id: "5563",
            children: [],
          },
          {
            name: "Olivia Lee",
            position: "VP of HR",
            email: "[email protected]",
            id: "5564",
            children: [
              {
                name: "Ethan Miller",
                position: "HR Manager",
                email: "[email protected]",
                id: "5565",
                children: [],
              },
            ],
          },
        ],
      },
    ],
  },
];

下面是一个早期的想法,我必须使用带有

x
y
道具的坐标对象来遍历树。

x
代表您所在的行,
y
代表列。

我尝试编写一个函数,每当用户单击向左、向右、向上或向下时,它都会分别增加列或行。

所以这些键盘点击(向下、向右、向下)最终会出现下面的结果,但是有了这些数字/坐标,我认为最终出现“Emily Wilson”并不是特别容易,甚至不可能

coords = {
    x: 2,
    y: 1,
}

我对如何解决这个问题相当迷茫。

非常感谢任何帮助。

javascript algorithm search binary-tree binary-search-tree
1个回答
0
投票

我建议使用

data
up
down
left
链接丰富
right
结构,并在执行导航步骤时遵循这些链接。

下面的递归函数

link
确保所有根节点(如果不止一个“Sarah Johnson”)也被链接以进行左/右导航。

const data = [{
  name: "Sarah Johnson",
  position: "CEO",
  email: "[email protected]",
  id: "5555",
  children: [{
      name: "Michael Davis",
      position: "CFO",
      email: "[email protected]",
      id: "5556",
      children: [{
          name: "Sophia Adams",
          position: "Finance Manager",
          email: "[email protected]",
          id: "5557",
          children: [],
        },
        {
          name: "William Harris",
          position: "Financial Analyst",
          email: "[email protected]",
          id: "5558",
          children: [],
        },
        {
          name: "Oliver Turner",
          position: "Accounting Manager",
          email: "[email protected]",
          id: "5559",
          children: [],
        },
      ],
    },
    {
      name: "Robert Smith",
      position: "COO",
      email: "[email protected]",
      id: "5560",
      children: [{
          name: "Emily Wilson",
          position: "VP of Operations",
          email: "[email protected]",
          id: "5561",
          children: [],
        },
        {
          name: "Daniel Brown",
          position: "Director of Production",
          email: "[email protected]",
          id: "5562",
          children: [],
        },
        {
          name: "Sophie Turner",
          position: "Director of Logistics",
          email: "[email protected]",
          id: "5563",
          children: [],
        },
        {
          name: "Olivia Lee",
          position: "VP of HR",
          email: "[email protected]",
          id: "5564",
          children: [{
            name: "Ethan Miller",
            position: "HR Manager",
            email: "[email protected]",
            id: "5565",
            children: [],
          }, ],
        },
      ],
    },
  ],
}, ];

function link(node) {
  if (node.children[0]) node.down = node.children[0];
  for (var i = 0; i < node.children.length; i++) {
    node.children[i].up = node;
    if (i > 0) {
      node.children[i].left = node.children[i - 1];
      node.children[i - 1].right = node.children[i];
    }
    link(node.children[i]);
  }
}
link({
  children: data
});
var current = data[0];
currentNode.textContent = current.name;
document.addEventListener("keyup", function(event) {
  var node;
  switch (event.which) {
    case 40:
      node = current.down;
      break;
    case 38:
      node = current.up;
      break;
    case 37:
      node = current.left;
      break;
    case 39:
      node = current.right;
      break;
  }
  if (node?.name) {
    current = node;
    currentNode.textContent = current.name;
  }
});
<span id="currentNode"></span>

© www.soinside.com 2019 - 2024. All rights reserved.