排序|二叉树遍历

几种排序
参考 掘金小册

function checkArray(array) {
  if (!array || array.length < 2) {
    return
  }
}

function swap(array, i, j) {
  var temp = array[i]
  array[i] = array[j]
  array[j] = temp
}
//冒泡
function bubble(array) {
  checkArray(array)
  for (var i = array.length - 1; i > 0; i--) {
    for (var j = 0; j < i; j++) {
      if (array[j] > array[j + 1]) {
        swap(array, j, j + 1)
      }
    }
  }
}
//插入
function insertion(array) {
  checkArray(array)
  for (var i = 1; i < array.length; i++) {
    for (var j = i - 1; j >= 0; j--) {
      if (array[j] > array[j + 1]) {
        swap(array, j, j + 1)
      }
    }
  }
}
//选择
function selection(array) {
  checkArray(array)
  for (var i = 0; i < array.length - 1; i++) {
    var minIndex = i
    for (var j = i + 1; j < array.length; j++) {
      minIndex = array[j] < array[minIndex] ? j : minIndex
    }
    swap(array, i, minIndex)
  }
}
//归并
function mergeSort(array, left, right) {
  if (left == right) return; //只有一个元素,直接返回
  let mid = parseInt(left + ((right - left) >> 1)); //位运算更高效
  mergeSort(array, left, mid);
  mergeSort(array, mid + 1, right); //二分都排序好了 接下来进行整体排序
  let p1 = left;
  let p2 = mid + 1;
  let i = 0;
  let result = []; //存放排序好的结果
  while (p1 <= mid && p2 <= right) {
    result[i++] = array[p1] < array[p2] ? array[p1++] : array[p2++];
  }
  while (p1 <= mid) {
    result[i++] = array[p1++];
  }
  while (p2 <= right) {
    result[i++] = array[p2++];
  }
  for (let j = 0; j < result.length; j++) {
    array[left + j] = result[j];
  }
  return array;
}

快排参考 阮一峰博客 http://www.ruanyifeng.com/blog/2011/04/quicksort_in_javascript.html

function quik(array) {
  if (array.length < 2) {
    return array
  }
  var index = Math.floor(array.length / 2); //基准值序号
  var item = array.splice(index, 1)[0]; //取出基准值
  var left = []; //比基准值小
  var right = []; //比基准值大
  for (var i = 0; i < array.length; i++) {
    if (array[i] < item) {
      left.push(array[i])
    }
    if (array[i] > item) {
      right.push(array[i])
    }
  }
  return quik(left).concat([item], quik(right))
}

非递归方式二叉树遍历

//非递归前序遍历
function pre(root) {
  let stack = []
  stack.push(root)
  while (stack.length != 0) {
    stack.pop();
    console.log(root);
    //栈是后进先出
    if (root.right) {
      stack.push(root.right)
    }
    if (root.left) {
      stack.push(root.left)
    }
  }
}
//非递归中序遍历
//中序遍历非递归思路
//(1) 循环终止条件:指针为空并且栈为空
//(2) 不断push左子树节点,直到为空。则弹出栈顶元素并把指针指向右子树。
function mid(root) {
  let stack = [];
  while (stack.length != 0 || root) {
    if (root) {
      stack.push(root);
      root = root.left;
    } else {
      root = stack.pop();
      console.log(root.value);
      root = root.right;
    }
  }
}
//非递归后序遍历
function after(root) {
  //用两个栈来实现 左-右-根 根在最后 所以要先压栈
  let stack1 = []
  let stack2 = []
  stack1.push(root)
  while (stack1.length != 0) {
    root = stack1.pop();
    stack2.push(root);
    if (root.left) {
      stack1.push(root.left);
    }
    if (root.right) {
      stack1.push(root.right);
    }
  }
  while (stack2.length) {
    console.log(stack2.pop());
  }
}

中序遍历的前驱后继
掘金小册这一部分把while条件的left和right写反了

function pre(node) {
  if (!node) {
    return
  }
  //目标节点的左节点不为空 返回左节点的最右节点
  if (node.left) {
    return getRight(node.left)
  } else {
    let parent = node.parent;
    //左节点为空 且为父节点的右节点 返回父节点
    //左节点为空 且为父节点的左节点 返回第一个是父节点右节点的节点 返回其父节点
    while (parent && parent.left == node) {
      node = parent;
      parent = node.parent;
    }
    return parent;
  }
}

function getRight(node) {
  if (!node) {
    return;
  }
  while (node.right) {
    node = node.right;
  }
  return node;
}

function next(node) {
  if (!node) {
    return
  }
  if (node.right) {
    return getLeft(node.right);
  } else {
    let parent = node.parent;
    while (parent && parent.right == node) {
      node = parent;
      parent = node.parent;
    }
    return parent
  }
}

function getLeft(node) {
  if (!node) {
    return
  }
  while (node.left) {
    node = node.left
  }
  return node
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值