[英]Add Doubly Linked List Node in Singly Linked List
给定单链表: 1 -> 2 -> 3 -> 4 -> 5 -> null
修改中间元素为双链表节点
这里中间元素是3
3 -> next
应指向4
3 -> prev
应该指向1
有人可以建议怎么做吗? 面试官给我提示use interface
。 但我不知道怎么做。
我必须遍历此链接列表并打印所有节点,当它到达中间时,打印next和prev指向的位置,然后打印到列表末尾。
Expected output
: 1, 2, Middle: 3, Prev: 1, Next: 4, 5
我在添加中间节点时遇到问题。
根据定义 ,单链列表仅包含单链节点,而双链列表仅包含双链节点。 除此以外。 两者都不是。
根据定义 ,双向链接列表的字段prev
必须指向上一个元素。
无论您打算建造什么。 没有明确说明。 因此,如果您在采访中真的被问到了这一点(并且没有误解这个问题-也许他想让您指出ghis 违反了界面?)这是http://thedailywtf.com/的代码恐怖故事的一种情况-“无能的面试官”。
因此,这是“ 有效的 ”,但是如果希望在采访中得到回答,那就太麻烦了。
链表
public class LinkedList {
public interface Linkable<V, L extends Linkable> {
V getValue();
L getNext();
void setNext(L link);
}
public static class Node implements Linkable<Integer, Linkable> {
int value;
Linkable next;
Node(int value) {
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
@Override
public Linkable getNext() {
return next;
}
@Override
public void setNext(Linkable link) {
this.next = link;
}
}
private Linkable head;
public boolean isEmpty() {
return this.head == null;
}
public Linkable getHead() {
return head;
}
public void add(int v) {
Node next = new Node(v);
if (isEmpty()) {
this.head = next;
} else {
Linkable tmp = this.head;
while (tmp.getNext() != null) {
tmp = tmp.getNext();
}
tmp.setNext(next);
}
}
}
接口
interface DoublyLinkable<V, L extends LinkedList.Linkable> extends LinkedList.Linkable<V,L> {
LinkedList.Linkable getPrev();
void setPrev(LinkedList.Linkable prev);
}
DoubleNode
public class DoubleNode extends LinkedList.Node implements DoublyLinkable<Integer, LinkedList.Linkable> {
LinkedList.Linkable prev;
public DoubleNode(int value) {
super(value);
}
@Override
public LinkedList.Linkable getPrev() {
return prev;
}
@Override
public void setPrev(LinkedList.Linkable prev) {
this.prev = prev;
}
}
司机
输出
1, 2, Middle: 3, Prev: 1, Next: 4, 5
public class Driver {
public static LinkedList getList() {
LinkedList list = new LinkedList();
for (int i = 1; i <= 5; i++) {
list.add(i);
}
return list;
}
public static void main(String[] args) {
LinkedList list = getList();
LinkedList.Linkable head = list.getHead();
LinkedList.Linkable beforeMiddle = null;
LinkedList.Linkable middle = list.getHead();
LinkedList.Linkable end = list.getHead();
if (head != null) {
// find the middle of the list
while (true) {
if (end.getNext() == null || end.getNext().getNext() == null) break;
beforeMiddle = middle;
middle = middle.getNext();
end = end.getNext().getNext();
}
// Replace middle by reassigning the pointer to it
if (beforeMiddle != null) {
DoubleNode n = new DoubleNode((int) middle.getValue()); // same value
n.setPrev(list.getHead()); // point back to the front
n.setNext(middle.getNext()); // point forward to original value
beforeMiddle.setNext((DoublyLinkable) n);
middle = beforeMiddle.getNext();
}
// Build the "expected" output
StringBuilder sb = new StringBuilder();
final String DELIMITER = ", ";
head = list.getHead();
boolean atMiddle = false;
if (head != null) {
do {
if (head instanceof DoublyLinkable) {
atMiddle = true;
String out = String.format("Middle: %d, Prev: %d, ", (int) head.getValue(), (int) ((DoublyLinkable) head).getPrev().getValue());
sb.append(out);
} else {
if (atMiddle) {
sb.append("Next: ");
atMiddle = false;
}
sb.append(head.getValue()).append(DELIMITER);
}
head = head.getNext();
} while (head != null);
}
sb.setLength(sb.length() - DELIMITER.length());
System.out.println(sb.toString());
}
}
}
如果没有,则最好定义一个lenght()函数,这样在给定一个链表的情况下,您可以知道它有多少个节点。
感谢Cereal_Killer对这个答案的先前版本的响应,我注意到列表首先是一个单链接列表,您只需要使中间节点既链接到下一个节点,又链接到某个先前的节点。
现在,我猜您已经定义了两个结构(Struct,Class或任何其他类型,具体取决于您使用的语言)。 因此,可以说你有Node_s
定义为只有一个节点next
指针, Node_d
同时具有next
和prev
指针。 ( Node_d
可以从Node_s
继承,因此您只需要在子类中添加prev
属性即可)。 知道了这一点,上面的代码应该可以满足您的需求:
函数do_it(my_LinkedListlinkedList){
int i_middle;
int length = linkedList.length();
if ( (length ÷ 2 ) != 0 ) i_middle = length / 2;
else return -1;
Node_s aux = linkedList.first();
int index = 0;
Node_d middle= null;
while (aux != null) {
if (index == i_middle - 1){ //now aux is the middle's previous node
middle.data = aux.next.data; //aux.next is the middle singly node, we assignate the data to the new double linked node
middle.prev = aux; //as we said, aux is the prev to the middle
midle.next = aux.next.next; //so aux.next.next is the next to the middle
print(what you need to print);
}else {
print("Node " + index " next: "+ aux.next);
}//end if
index++;
aux = aux.next;
} //end while
}//end function
前面的代码应该可以满足您的需求。 我用某种伪Java代码编写了答案,所以如果您不熟悉Java或不了解我的伪代码做什么,请告诉我。 无论如何,我的代码的想法可能会遇到麻烦,具体取决于您使用的语言,因此您必须对其进行调整。
请注意,在该程序执行结束时,您的数据结构将不是一个单链表,也不是一个双链表,因为您将拥有linkedList.length() - 1
节点以一种有符号的方式链接,但是中间一个将有两个链接。
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.