用数组实现队列

enqueue:元素入队
dequeue:元素出队
size:返回队列长度
showHead: 查看队头元素

  1. class Queue {
  2. constructor() {
  3. this.dataStore = [];
  4. }
  5. enqueue(element) {
  6. this.dataStore.push(element);
  7. }
  8. dequeue() {
  9. return this.dataStore.shift();
  10. }
  11. size() {
  12. return this.dataStore.length();
  13. }
  14. showHead() {
  15. return this.dataStore[0];
  16. }
  17. }

用数组和两个指针实现队列

  1. class Queue {
  2. constructor() {
  3. this.dataStore = [];
  4. this.rear = -1; //指向最后一个元素
  5. this.front = -1; // 指向第一个元素的下标-1
  6. }
  7. enqueue(element) {
  8. // 入队队尾下标+1
  9. this.dataStore[++this.rear] = element;
  10. }
  11. dequeue() {
  12. // 出队队首下标+1
  13. if (this.isEmpty()) return;
  14. return this.dataStore[++this.front];
  15. }
  16. size() {
  17. return this.rear - this.front;
  18. }
  19. showHead() {
  20. // front+1才是队首元素
  21. if (!this.isEmpty()) return this.dataStore[this.front+1];
  22. }
  23. isEmpty() {
  24. return this.rear === this.front;
  25. }
  26. }

使用数组实现环形队列

  1. class CircularQueue {
  2. constructor(maxSize) {
  3. this.maxSize = maxSize;
  4. this.dataStore = [];
  5. this.rear = 0; //只要rear与front相等就是空队列,初始值无要求
  6. this.front = 0;
  7. }
  8. enqueue(element) {
  9. // 入队队尾下标+1,取模达到环形队列效果
  10. if (this.isFull()) {
  11. return console.log("full");
  12. }
  13. this.rear = (this.rear + 1) % this.maxSize;
  14. this.dataStore[this.rear] = element;
  15. }
  16. dequeue() {
  17. // 出队队首下标+1,取模达到环形队列效果
  18. if (this.isEmpty()) {
  19. return console.log("empty");
  20. }
  21. this.front = (this.front + 1) % this.maxSize;
  22. return this.dataStore[this.front];
  23. }
  24. size() {
  25. // 加上maxSize以免出现负数的情况,再取模以免结果大于maxSize
  26. return (this.rear - this.front + this.maxSize) % this.maxSize;
  27. }
  28. showHead() {
  29. // front+1才是队首元素,同时取模以免溢出
  30. if (!this.isEmpty()) return this.dataStore[(this.front + 1) % this.maxSize];
  31. }
  32. isEmpty() {
  33. return this.rear === this.front;
  34. }
  35. isFull() {
  36. return (this.rear + 1) % this.maxSize === this.front;
  37. }
  38. }

把无序数组调整成大顶堆

  1. // 调整位置方法
  2. function shiftDown(start, length, arr) {
  3. //从上而下调整堆的顺序
  4. let i = start;
  5. let j = 2 * i + 1;
  6. const temp = arr[i];
  7. while (j < length) {
  8. if (arr[j] < arr[j + 1] && j < length - 1) j++; //由于是大顶堆,取大的节点
  9. if (temp < arr[j]) {
  10. // 如果比开始节点大就往上浮,也可以理解成开始节点比叶子节点小就跟叶子节点换位,一直往下换到正确的位置
  11. arr[i] = arr[j];
  12. } else {
  13. //若左右两个叶子都比根节点小,由于这是个堆结构,它的叶子的叶子节点也会比根节点小,不需要继续调整
  14. break;
  15. }
  16. i = j;
  17. j = j * 2 + 1;
  18. }
  19. arr[i] = temp;
  20. }
  21. function makeHeap(arr) {
  22. // 把数组变成大顶堆
  23. for (let i = ~~(arr.length / 2) - 1; i > -1; i--) {
  24. //从下而上局部排序,直到把数组排成一个大顶堆
  25. shiftDown(i, arr.length, arr);
  26. }
  27. return arr;
  28. }

用大顶堆实现堆排序

  1. function createArr(num) {
  2. const arr = new Array(num);
  3. for (let i = 0; i < num; i++) {
  4. arr[i] = ~~(Math.random() * 10000);
  5. }
  6. return arr;
  7. }
  8. // 调整位置方法
  9. function shiftDown(start, length, arr) {
  10. //从上而下调整堆的顺序
  11. let i = start;
  12. let j = 2 * i + 1;
  13. const temp = arr[i];
  14. while (j < length) {
  15. if (arr[j] < arr[j + 1] && j < length - 1) j++; //由于是大顶堆,取大的节点
  16. if (temp < arr[j]) {
  17. // 如果比开始节点大就往上浮,也可以理解成开始节点比叶子节点小就跟叶子节点换位,一直往下换到正确的位置
  18. arr[i] = arr[j];
  19. } else {
  20. //若左右两个叶子都比根节点小,由于这是个堆结构,它的叶子的叶子节点也会比根节点小,不需要继续调整
  21. break;
  22. }
  23. i = j;
  24. j = j * 2 + 1;
  25. }
  26. arr[i] = temp;
  27. }
  28. function makeHeap(arr) {
  29. // 把数组变成大顶堆
  30. for (let i = ~~(arr.length / 2) - 1; i > -1; i--) {
  31. //从下而上局部排序,直到把数组排成一个大顶堆
  32. shiftDown(i, arr.length, arr);
  33. }
  34. return arr;
  35. }
  36. function heapSort(arr) {
  37. arr = makeHeap(arr)
  38. // 依次把最大的元素剔除,然后调整剩余元素,这样可以按大小依次剔除元素,达到排序效果
  39. for (let j = arr.length - 1; j > 0; j--) {
  40. //把最大值与末尾调换,去除末尾元素,剩余再次调整成一个大顶堆,
  41. // 此时首位又是剩余元素的最大值,一直交换调整直到所有元素排序完毕
  42. const temp = arr[0];
  43. arr[0] = arr[j];
  44. arr[j] = temp;
  45. shiftDown(0, j, arr);
  46. }
  47. }
  48. // 测试堆排序的时间
  49. const arr = createArr(8000000);
  50. console.time();
  51. heapSort(arr);
  52. console.timeEnd();

用堆实现优先队列

  1. class PriorityQueue {
  2. constructor(isMax) {
  3. this.isMax = isMax; // 是否优先最大值出列
  4. this.arr = [];
  5. }
  6. shiftMaxUp() { // 自底向上调整
  7. const { arr } = this;
  8. let i = arr.length - 1;
  9. let j = ~~((i + 1) / 2) - 1;
  10. let temp = arr[i];
  11. while (j >= 0) {
  12. if (temp > arr[j]) {
  13. arr[i] = arr[j];
  14. } else {
  15. break;
  16. }
  17. i = j;
  18. j = j = ~~((j + 1) / 2) - 1;
  19. }
  20. arr[i] = temp;
  21. }
  22. shiftMinUp() { // 自底向上调整
  23. const { arr } = this;
  24. let i = arr.length - 1;
  25. let j = ~~((i + 1) / 2) - 1;
  26. let temp = arr[i];
  27. while (j >= 0) {
  28. if (temp < arr[j]) {
  29. arr[i] = arr[j];
  30. } else {
  31. break;
  32. }
  33. i = j;
  34. j = j = ~~((j + 1) / 2) - 1;
  35. }
  36. arr[i] = temp;
  37. }
  38. shiftDownMax() { // 自顶向下调整
  39. const { arr } = this;
  40. if (!arr.length) {
  41. return arr;
  42. }
  43. let i = 0;
  44. let j = 2 * i + 1;
  45. let temp = arr[0];
  46. while (j < arr.length) {
  47. if (arr[j] < arr[j + 1] && j < arr.length - 1) {
  48. j++;
  49. }
  50. if (temp < arr[j]) {
  51. arr[i] = arr[j];
  52. } else {
  53. break;
  54. }
  55. i = j;
  56. j = j * 2 + 1;
  57. }
  58. arr[i] = temp;
  59. }
  60. shiftDownMin() { // 自顶向下调整
  61. const { arr } = this;
  62. if (!arr.length) {
  63. return arr;
  64. }
  65. let i = 0;
  66. let j = 2 * i + 1;
  67. let temp = arr[0];
  68. while (j < arr.length) {
  69. if (arr[j] > arr[j + 1] && j < arr.length - 1) {
  70. j++;
  71. }
  72. if (temp > arr[j]) {
  73. arr[i] = arr[j];
  74. } else {
  75. break;
  76. }
  77. i = j;
  78. j = j * 2 + 1;
  79. }
  80. arr[i] = temp;
  81. }
  82. add(num) { // 插入元素的时候在数组最后,也就是在叶子节点,需要往上调整位置
  83. const { arr, isMax } = this;
  84. arr.push(num);
  85. if (isMax) {
  86. this.shiftMaxUp();
  87. } else {
  88. this.shiftMinUp();
  89. }
  90. }
  91. delete() { // 删除时把队尾放到队首,此时可以从上到下调整位置
  92. const { arr, isMax } = this;
  93. arr[0] = arr[arr.length - 1];
  94. arr.pop();
  95. if (isMax) {
  96. this.shiftDownMax();
  97. } else {
  98. this.shiftDownMin();
  99. }
  100. }
  101. size() {
  102. return this.arr.length;
  103. }
  104. get() {
  105. return this.arr[0];
  106. }
  107. }