得到拓扑排序的所有拓扑序列

449 阅读1分钟
/**
 * 尽可能多的得到拓扑序列 在正常的基础上 记录可交换顺序的元素
 * @param {*} total
 * @param {*} prerequisites
 */
function tpSortBFS(total, prerequisites) {
  // console.log()
  //结果
  let result = ''

  //用来存储节点的后续节点
  let nodeInfo = []

  //用来存储节点入度情况
  let rdArr = new Array(total).fill(0)

  //转化传入进来的二维数组
  for (let i = 0; i < prerequisites.length; i++) {
    //先决条件
    const prerequisiteNum = prerequisites[i][1]
    const subsequentNum = prerequisites[i][0]
    if (nodeInfo[prerequisiteNum] === undefined) {
      nodeInfo[prerequisiteNum] = [subsequentNum]
    } else {
      nodeInfo[prerequisiteNum].push(subsequentNum)
    }
    rdArr[subsequentNum]++
  }
  const canChangeArr = new Array(1).fill([])

  //找到所有入度为零的节点
  const entryArr = []
  for (let i = 0, len = rdArr.length; i < len; i++) {
    if (rdArr[i] === 0) {
      entryArr.push(i)
      canChangeArr[0].push(i)
    }
  }
  let count = 0

  while (entryArr.length) {
    count++

    const node = entryArr.shift()

    canChangeArr[count] = []

    //找到该节点的后续节点,将后续节点的入度数做相应的减法
    if (nodeInfo[node] && nodeInfo[node].length > 0) {
      // console.log(entryArr[entryArr.length - 1], node)
      for (let i = 0, len = nodeInfo[node].length; i < len; i++) {
        //当前节点
        const item = nodeInfo[node][i]
        //当前节点的入度减去1
        rdArr[item]--
        if (rdArr[item] === 0) {
          canChangeArr[count].push(item)
          entryArr.push(item)
        }
      }
    }
  }
  const a = canChangeArr.filter((item) => item.length !== 0)
  const sortArr = []
  for(let i = 0,len = a.length;i < len;i++) {
    const item = a[i];
    if(item.length > 1) {
      sortArr[i] = [...allSort(a[i])]
    }else {
      sortArr[i] = item[0]
    }
  }
  const r = sortOrder(sortArr)
  console.log('最终的结果',r);
  return r
}

/**
 * 全排列 
 * @param {} inputArr 
 */
function allSort(inputArr) {
  const inputLength = inputArr.length
  const result = []
  const cb = (val) => {
    result.push(val)
  }
  const run = (arr, pre = '') => {
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i]
      let preStr = pre + item
      if (preStr.length === inputLength) {
        cb(preStr)
      } else {
        run(
          arr.filter((_item) => _item !== item),
          preStr
        )
      }
    }
    
    return result
  }
  return run(inputArr)
}


/**
 * 得到有序数组的所有可能性
 * @param {*} inputArr 
 */
function sortOrder(inputArr) {
  const result = []
  const length = inputArr.length
  function cb(v) {
    result.push(v.join(''))
  }
  function run(params,pre=[]) {
    for(let i = 0;i < params.length;i++) {
      const item = params[i]
      if(Array.isArray(item) && item.length > 1) {
        for(let j = 0;j < item.length;j++) {
          run(params.slice(i+1),[...pre,item[j]])
        }
      }else {
        pre = [...pre,item]
        if(pre.length === length) {
          cb(pre)
        }
      }
    }
  }

  run(inputArr)
  return result
}


tpSortBFS(6, [
  [3, 0],
  [3, 1],
  [4, 1],
  [2, 1],
  [4, 2],
  [5, 3],
  [5, 4],
])

tpSortBFS(4, [
  [1, 0],
  [2, 0],
  [3, 1],
  [3, 2],
])