We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
排序这块我们已经讨论很多了( #6 #8 #9 #10 ),从最开始基本的冒泡、插入、选择和希尔排序,到分治思想的延伸——归并排序(自顶向下和自底向上),再到归并排序的互补算法——快排,然后学习了新的数据结构——二叉堆,于是有了堆排序。
二叉堆是一种数据结构,他的每一个二叉树点元素数值都会比下面两个节点元素的数值要大,因为这种数据接口包含的信息量很大,而得到这种数据结构的成本是很低的,构建一个二叉堆的算法并不复杂:
/chapters/chapter-2-sorting/2.4-priority-queues/priorityQueueAdd.js
function priorityQueueAdd(input) { var output = []; output[1] = input[0]; for(var i = 1, len = input.length; i < len; i++) { output = swim(output, input[i]); } return output; function swim(arr, val) { arr.push(val); var k = arr.length - 1; while(k > 1 && arr[k >> 1] < arr[k]) { var p = k >> 1; arr[p] = [arr[k], arr[k] = arr[p]][0]; k = p; } return arr; } }
通过上浮的方式,不断插入新元素,既可形成一个二叉堆。这种优先队列最大的特点是,能够拿到很快拿到最大元素(顶部),当这个最大元素被删除(优先级最高的事务被处理完成)时,还能快速高效地将剩下的元素重整为一个二叉堆:
/chapters/chapter-2-sorting/2.4-priority-queues/priorityQueueDelete.js
function priorityQueueDelete(input) { var output = []; input.splice(1, 1); output = sink(input); return output; function sink(arr) { arr.splice(1, 0, arr.pop()); var k = 1, N = arr.length - 1; while(2 * k <= N) { var j = 2 * k; if(j < N && arr[j] < arr[j + 1]) j++; if(arr[k] >= arr[j]) break; arr[k] = [arr[j], arr[j] = arr[k]][0]; k = j; } return arr; } }
一个二叉堆能够快速拿到最大元素,并且能够立即重新调整为二叉堆,基于这个特性,就有了堆排序:
/chapters/chapter-2-sorting/2.4-priority-queues/heapSort.js
function heapSort(input) { return sort(input); function sort (arr){ var N = arr.length - 1; for(var k = N >> 2; k >= 1; k--) { arr = sink(arr, k, N); } while(N > 1) { arr[1] = [arr[N], arr[N] = arr[1]][0]; N--; arr = sink(arr, 1, N); } return arr; } function sink(arr, k, N) { while(2 * k <= N) { var j = 2 * k; if(j < N && arr[j] < arr[j + 1]) j++; if(arr[k] >= arr[j]) break; arr[k] = [arr[j], arr[j] = arr[k]][0]; k = j; } return arr; } }
光看代码还是挺难理解的,脑海中必须有一个数组储存的堆模型。for 循环构造了堆(从 N/2 开始,跳过了所有大小为 1 的堆),注意,这里构造的并不是二叉堆,然后 while 循环将最大的元素 a[1] 和 a[n] 交换位置并修复堆,如此循环直到堆为空。
上面的排序用到的是 sink 方法,而 swim 方法也是可以用于排序算法之中的,这就是对应的下沉排序,感觉有点难理解。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
排序这块我们已经讨论很多了( #6 #8 #9 #10 ),从最开始基本的冒泡、插入、选择和希尔排序,到分治思想的延伸——归并排序(自顶向下和自底向上),再到归并排序的互补算法——快排,然后学习了新的数据结构——二叉堆,于是有了堆排序。
二叉堆是一种数据结构,他的每一个二叉树点元素数值都会比下面两个节点元素的数值要大,因为这种数据接口包含的信息量很大,而得到这种数据结构的成本是很低的,构建一个二叉堆的算法并不复杂:
/chapters/chapter-2-sorting/2.4-priority-queues/priorityQueueAdd.js
通过上浮的方式,不断插入新元素,既可形成一个二叉堆。这种优先队列最大的特点是,能够拿到很快拿到最大元素(顶部),当这个最大元素被删除(优先级最高的事务被处理完成)时,还能快速高效地将剩下的元素重整为一个二叉堆:
/chapters/chapter-2-sorting/2.4-priority-queues/priorityQueueDelete.js
一个二叉堆能够快速拿到最大元素,并且能够立即重新调整为二叉堆,基于这个特性,就有了堆排序:
/chapters/chapter-2-sorting/2.4-priority-queues/heapSort.js
光看代码还是挺难理解的,脑海中必须有一个数组储存的堆模型。for 循环构造了堆(从 N/2 开始,跳过了所有大小为 1 的堆),注意,这里构造的并不是二叉堆,然后 while 循环将最大的元素 a[1] 和 a[n] 交换位置并修复堆,如此循环直到堆为空。
上面的排序用到的是 sink 方法,而 swim 方法也是可以用于排序算法之中的,这就是对应的下沉排序,感觉有点难理解。
The text was updated successfully, but these errors were encountered: