几种排序
参考 掘金小册
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
}