下面是使用gpt生成的双向循环列表:可将数组/数字转链表,
该实现包括双向循环列表的常用操作,如元素插入、元素删除等。
同时也提供了一些辅助方法,如获取链表长度、判断链表是否为空以及打印链表等。
但是在实际使用中也出现了一些问题
- gpt的反转链表方法报错
- 经过提示之后依旧不能生成准确的代码
- 在生成代码时不会结合之前的代码,每一次的方法代码都是独立的,代码冗余
- 不要轻易相信chatgpt在生成之后依旧需要自己检查一遍逻辑,
- gpt之能在开始之前给一些辅助,而不能代替完成任务。
class ListNode {
constructor(val, prev, next) {
this.val = val;
this.prev = prev ? prev : null;
this.next = next ? next : null;
}
}
class DoublyCircularLinkedList {
constructor(data) {
if (typeof data === 'number') {
this.head = new ListNode(data);
this.head.prev = this.head;
this.head.next = this.head;
} else if (Array.isArray(data)) {
if (!data || data.length === 0) {
this.head = null;
return;
}
this.head = new ListNode(data[0]);
let tail = this.head;
for (let i = 1; i < data.length; i++) {
const node = new ListNode(data[i], tail, this.head);
tail.next = node;
tail = node;
this.head.prev = tail;
}
tail.next = this.head;
}
}
toArray() {
const arr = [];
let curr = this.head;
do {
arr.push(curr.val);
curr = curr.next;
} while (curr !== this.head);
return arr;
}
// length():返回链表长度。
length() {
let count = 0;
let curr = this.head;
while (curr) {
count++;
curr = curr.next;
if (curr === this.head) break;
}
return count;
}
// isEmpty():判断链表是否为空。
isEmpty() {
return this.head === null;
}
// prepend(val):在链表头部添加一个节点。
prepend(val) {
const node = new ListNode(val, null, this.head);
if (this.head) {
node.prev = this.head.prev;
this.head.prev.next = node;
this.head.prev = node;
} else {
node.prev = node;
node.next = node;
}
this.head = node;
return this;
}
// append(val):在链表末尾添加一个节点。
append(val) {
const node = new ListNode(val, null, null);
if (!this.head) {
node.prev = node;
node.next = node;
this.head = node;
} else {
node.prev = this.head.prev;
node.next = this.head;
this.head.prev.next = node;
this.head.prev = node;
}
return this;
}
// insert(val, index):在指定位置插入一个节点。
insert(val, index) {
if (index < 0 || index > this.length()) {
return null;
}
if (index === 0) {
return this.prepend(val);
}
if (index === this.length()) {
return this.append(val);
}
let curr = this.head;
for (let i = 0; i < index; i++) {
curr = curr.next;
}
const node = new ListNode(val, curr.prev, curr);
curr.prev.next = node;
curr.prev = node;
return this;
}
// remove(val):删除值等于 val 的第一个节点。
remove(val) {
if (!this.head) {
return null;
}
let curr = this.head;
while (curr.val !== val) {
curr = curr.next;
if (curr === this.head) {
return null;
}
}
if (this.length() === 1) {
this.head = null;
} else if (curr === this.head) {
this.head = this.head.next;
this.head.prev = curr.prev;
curr.prev.next = this.head;
} else {
curr.prev.next = curr.next;
curr.next.prev = curr.prev;
}
return this;
}
// removeAt(index):删除指定位置的节点。
removeAt(index) {
if (index < 0 || index >= this.length()) {
return null;
}
if (index === 0) {
this.head = this.head.next;
if (this.head) {
this.head.prev = this.head.prev.prev;
this.head.prev.next = this.head;
}
} else {
let curr = this.head;
for (let i = 0; i < index; i++) {
curr = curr.next;
}
curr.prev.next = curr.next;
curr.next.prev = curr.prev;
}
return this;
}
// indexOf(val):查找值等于 val 的第一个节点的位置。
indexOf(val) {
let curr = this.head;
let index = 0;
while (curr && curr.val !== val) {
curr = curr.next;
index++;
if (curr === this.head) {
return -1;
}
}
return curr ? index : -1;
}
//reverse():翻转链表。
reverse() {
if (!this.head || !this.head.next||this.length==1) {
return this;
}
this.insert(0,0)
let curr = this.head;
do {
let next = curr.next;
let temp = curr.prev;
curr.prev = curr.next;
curr.next = temp;
curr = next;
} while (curr !== this.head)
this.removeAt(0)
return this;
}
// 打印链表
print() {
if (!this.head) {
console.log("[]");
return;
}
let curr = this.head;
const arr = [];
do {
arr.push(curr.val);
curr = curr.next;
} while (curr !== this.head);
console.log(arr);
}
}
const arr = [1, 2, 3, 4, 5];
const num = 2;
const list1 = new DoublyCircularLinkedList(arr);
const list2 = new DoublyCircularLinkedList(num);
console.log(list1.length()); // 5
console.log(list2.isEmpty()); // false
console.log(list1.prepend(0).toArray()); // [0, 1, 5, 3, 9, 4]
console.log(list1.append(6).toArray()); // [0, 1, 5, 3, 9, 4, 6]
console.log(list1.insert(2, 2).toArray()); // [0, 1, 2, 5, 3, 9, 4, 6]
console.log(list1.remove(2).toArray()); // [0, 1, 5, 3, 9, 4, 6]
console.log(list1.removeAt(3).toArray()); // [0, 1, 5, 9, 4, 6]
console.log(list1.indexOf(5)); // 2
console.log(list1.reverse().toArray()); // [6, 4, 9, 5, 1, 0]
console.log(list2.reverse().toArray()); // [6, 4, 9, 5, 1, 0]
list2.reverse().print(); // [6, 4, 9, 5, 1, 0]