我正在尝试解决涉及链表的问题。对链接列表进行分区,以使小于分区的值排在最前面,然后是等于或大于分区的值。
示例:
input: 90 -> 30 -> 40 -> 50 -> 100 -> 40
partition: 50
output: 30 -> 40 -> 40 -> 50 -> 100 -> 90
所有小于分区(50)的节点都比所有大于分区(50)的节点先出现。
function partitionLl(node) {
let list = {
"head": {
"data": 90,
"next": {
"data": 30,
"next": {
"data": 40,
"next": {
"data": 50,
"next": {
"data": 100,
"next": {
"data": 40,
"next": {
"data": 15,
"next": {
"data": 90,
"next": {
"data": 200,
"next": {
"data": 90,
"next": {
"data": 10,
"next": {
"data": 90,
"next": null
}
}
}
}
}
}
}
}
}
}
}
}
}
let test;
let current = list.head;
let p1 = {
data: null,
next: null
};
let p2 = current;
while (current !== null) {
if (current.data < node) {
p1 = current;
p1 = p1.next;
} else {
p2 = current;
p2 = p2.next;
}
current = current.next;
}
console.log(p1)
console.log(p2)
}
partitionLl(50)
这是我拥有的代码,我想要获得的列表在循环中很棒,它具有我需要的列表。问题是我需要在循环完成时附加这些列表(p1和p2),但是当在while循环之外时,变量记录的内容完全不同且不准确。
在循环的内部和外部都跟踪当前变量。不知道为什么会这样,或者不确定哪种作用域循环会导致这种情况。我将如何在循环外访问这些值?
答案 0 :(得分:1)
OPs程序的问题在于它从不实际更改列表,也没有为结果建立新列表,即,从未发生对数据或下一个属性的分配。仅移动“指针” p1和p2,直到到达列表的末尾。 p1或p2的分配方式最终都将为空。
一种解决方案将创建当前元素的副本,并通过设置下一个属性将其附加到p1或p2。
像这样:
function partitionLl(node) {
let list = {
"head": {
"data": 90,
"next": {
"data": 30,
"next": {
"data": 40,
"next": {
"data": 50,
"next": {
"data": 100,
"next": {
"data": 40,
"next": {
"data": 15,
"next": {
"data": 90,
"next": {
"data": 200,
"next": {
"data": 90,
"next": {
"data": 10,
"next": {
"data": 90,
"next": null
}
}
}
}
}
}
}
}
}
}
}
}
}
let p1 = {
"head": null
}
let t1 = p1.head
let p2 = {
"head": null
}
let t2 = p2.head
let current = list.head
while (current !== null) {
if (current.data < node) {
if(p1.head === null) {
p1.head = {
"data": current.data,
"next": null
}
t1 = p1.head
} else {
t1.next = {
"data": current.data,
"next": null
}
t1 = t1.next
}
} else {
if(p2.head === null) {
p2.head = {
"data": current.data,
"next": null
}
t2 = p2.head
} else {
t2.next = {
"data": current.data,
"next": null
}
t2 = t2.next
}
}
current = current.next;
}
console.log(p1)
console.log(p2)
}
partitionLl(50)
答案 1 :(得分:0)
通常使用链接列表是使用递归的练习。
我将构建一些用于处理链表的原语,然后将它们组合以产生所需的结果-partition
可以从filter
和concat
来构建:
// given a list return a new list that contains only those items than pass the test function
const filter = (list, test) => {
const next = list.next ? filter(list.next, test) : null;
if (test(list.data)) {
return { data: list.data, next };
}
return next;
};
// given two lists return a new list with them concatenated together
const concat = (l1, l2) => {
if (!l1.next) {
return { data: l1.data, next: l2 };
}
return { data: l1.data, next: concat(l1.next, l2) };
};
const partition = (list, value) => {
const smaller = filter(list, d => d < value);
const bigger = filter(list, d => d >= value);
return concat(smaller, bigger);
};
答案 2 :(得分:0)
对于较小的值,您可以采用三个列表:(a)left
; (b)大于或等于right
; (c)将right
部分分为first
和last
,其中所有值进入last
列表,直到找到枢轴值,然后所有值进入first
。
最后,将所有列表合并为一个列表,然后返回一个新列表。
function partition(list, pivot) {
var leftHead = {},
left = leftHead,
firstHead = {},
lastHead = {},
right = lastHead,
isLast = true,
node = list.head;
while (node) {
if (node.data === pivot && isLast) {
right = firstHead;
isLast = false;
}
if (node.data < pivot) {
left.next = { data: node.data };
left = left.next;
} else {
right.next = { data: node.data };
right = right.next;
}
node = node.next;
}
if (firstHead.next) {
right.next = lastHead.next;
left.next = firstHead.next;
} else {
left.next = lastHead.next;
}
return { head: leftHead.next };
}
var list1 = { head: { data: 90, next: { data: 30, next: { data: 40, next: { data: 50, next: { data: 100, next: { data: 40, next: { data: 15, next: { data: 90, next: { data: 200, next: { data: 90, next: { data: 10, next: { data: 90, next: null } } } } } } } } } } } } },
list2 = { head: { data: 90, next: { data: 30, next: { data: 40, next: { data: 50, next: { data: 100, next: { data: 40 } } } } } } };
console.log(partition(list1, 50));
console.log(partition(list2, 50));
.as-console-wrapper { max-height: 100% !important; top: 0; }