在 JavaScript 中的链表中实现排序冒泡排序或其他

问题描述

我正在尝试在 JavaScript 中为链表实现冒泡排序。我一直在寻找类似的问题,但只在 C++ 或 Java 中找到了实现。我会很感激你的帮助。 做 BubbleSort 会很棒,但如果有其他排序选项,我也会很高兴看到它们的实现。我尝试了不同的选项来实现链表中的排序,但它们没有用。 现在我只有在列表的开头或结尾添加元素的方法。 下面是列表的实现。

LinkedListNode

export class LinkedListNode {
  public value;
  public prev;
  public next;

  constructor(value) {
    this.value = value;
    this.next = null;
    this.prev = null;
  }
}

链表

import { LinkedListNode } from './LinkedListNode';

export class LinkedList {
  private head;
  private tail;

  addHeadNode = (value) => {
    const newLinkendListNode = new LinkedListNode(value);

    if (!this.head) {
      this.head = newLinkendListNode;
      this.tail = newLinkendListNode;
    } else {
      this.head.prev = newLinkendListNode;
      newLinkendListNode.next = this.head;
      this.head = newLinkendListNode;
    }
  };

  addTailNode = (value) => {
    const newLinkendListNode = new LinkedListNode(value);

    if (!this.tail) {
      this.head = newLinkendListNode;
      this.tail = newLinkendListNode;
    } else {
      this.tail.next = newLinkendListNode;
      newLinkendListNode.prev = this.tail;
      this.tail = newLinkendListNode;
    }
  };

  getByIndex = index => {
    let currentNode = this.head;
    let count = 0;

    while (currentNode) {
      if (count === index) {
        console.log(currentNode);
        return currentNode;
      }
      count++;
      currentNode = currentNode.next;
    }
    return -1;
  };
}

解决方法

加入这个方法可以实现冒泡排序:

    bubbleSort() {
        let last = this.tail;
        while (last) {
            let node = this.head;
            while (node != last) {
                let next = node.next
                if (node.value > next.value) { // swap
                    [node.value,next.value] = [next.value,node.value];
                }
                node = next;
            }
            last = last.prev; // shorten the range that must be bubbled through
        }
    }

这里它与您的代码结合在一起(但使用纯 JavaScript,并允许构造函数接受一个参数):

class LinkedListNode {
    constructor(value) {
        this.value = value;
        this.next = null;
        this.prev = null;
    }
}

class LinkedList {
    constructor(iterable) { // Allow to initialise from an iterable
        this.head = null;
        this.tail = null;
        if (iterable) {
            for (let value of iterable) this.addTailNode(value);
        }
    }

    addHeadNode(value) {
        const newLinkendListNode = new LinkedListNode(value);

        if (!this.head) {
            this.head = newLinkendListNode;
            this.tail = newLinkendListNode;
        } else {
            this.head.prev = newLinkendListNode;
            newLinkendListNode.next = this.head;
            this.head = newLinkendListNode;
        }
    }

    addTailNode(value) {
        const newLinkendListNode = new LinkedListNode(value);

        if (!this.tail) {
            this.head = newLinkendListNode;
            this.tail = newLinkendListNode;
        } else {
            this.tail.next = newLinkendListNode;
            newLinkendListNode.prev = this.tail;
            this.tail = newLinkendListNode;
        }
    }

    getByIndex(index) {
        let currentNode = this.head;

        while (currentNode) {
            if (!index--) return currentNode;
            currentNode = currentNode.next;
        }
        return null;
    }
    
    bubbleSort() {
        let last = this.tail;
        while (last) {
            let node = this.head;
            while (node != last) {
                let next = node.next
                if (node.value > next.value) { // swap
                    [node.value,node.value];
                }
                node = next;
            }
            last = last.prev; // shorten the range that must be bubbled through
        }
    }
    
    * [Symbol.iterator]() {
        let node = this.head;
        while (node) {
            yield node.value;
            node = node.next;
        }
    }
    
    toString() {
        return Array.from(this).join(",");
    }
}

// Demo
let list = new LinkedList([1,10,5,7,3,2,9,8,4,6]);
console.log("before:",String(list));
list.bubbleSort();
console.log("after: ",String(list));

请注意,它通过交换值而不是节点来执行交换。这是一个更便宜的操作。