[英]Add Doubly Linked List Node in Singly Linked List
Given singly Linked List: 1 -> 2 -> 3 -> 4 -> 5 -> null
给定单链表:
1 -> 2 -> 3 -> 4 -> 5 -> null
Modify middle element as doubly Linked List Node 修改中间元素为双链表节点
here middle element is 3
这里中间元素是
3
3 -> next
should point to 4
3 -> next
应指向4
3 -> prev
should point to 1
3 -> prev
应该指向1
Can any one suggest how can it be done ? 有人可以建议怎么做吗? interviewer gave me hint
use interface
. 面试官给我提示
use interface
。 but I couldn't figure it out how. 但我不知道怎么做。
I have to iterate over this linked list and print all the node and when it reaches to the middle, print where next and prev is pointing to, then print till the end of the list. 我必须遍历此链接列表并打印所有节点,当它到达中间时,打印next和prev指向的位置,然后打印到列表末尾。
Expected output
: 1, 2, Middle: 3, Prev: 1, Next: 4, 5
Expected output
: 1, 2, Middle: 3, Prev: 1, Next: 4, 5
I'm facing problem in adding the middle node. 我在添加中间节点时遇到问题。
By definition , a single-linked list consists of single-linked nodes only, and a double-linked consists of double-linked nodes only. 根据定义 ,单链列表仅包含单链节点,而双链列表仅包含双链节点。 Otherwise.
除此以外。 it is neither.
两者都不是。
By definition the field prev
of a double-linked list must point to the previous element. 根据定义 ,双向链接列表的字段
prev
必须指向上一个元素。
Whatever you are supposed to build. 无论您打算建造什么。 It's something not well specified.
没有明确说明。 So if you really were asked this in an interview (and did not misunderstand the question - maybe he wanted you to point out that ghis violates the interface?) this is a case for the code horror stories of http://thedailywtf.com/ - section "incompetent interviewers".
因此,如果您在采访中真的被问到了这一点(并且没有误解这个问题-也许他想让您指出ghis 违反了界面?)这是http://thedailywtf.com/的代码恐怖故事的一种情况-“无能的面试官”。
So, this " works ", but if this is expected to be answered on an interview, it is way too much work. 因此,这是“ 有效的 ”,但是如果希望在采访中得到回答,那就太麻烦了。
LinkedList 链表
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 接口
interface DoublyLinkable<V, L extends LinkedList.Linkable> extends LinkedList.Linkable<V,L> {
LinkedList.Linkable getPrev();
void setPrev(LinkedList.Linkable prev);
}
DoubleNode 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;
}
}
Driver 司机
Outputs 输出
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());
}
}
}
If you haven't, you'd better define a lenght() function so given one linked list you can know how many nodes does it have. 如果没有,则最好定义一个lenght()函数,这样在给定一个链表的情况下,您可以知道它有多少个节点。
Thanks to the response of Cereal_Killer to the previous version of this answer, I noticed that the list is firstly a singly linked list, and you just have to make the middle node be linked both to the next node and to some previous node. 感谢Cereal_Killer对这个答案的先前版本的响应,我注意到列表首先是一个单链接列表,您只需要使中间节点既链接到下一个节点,又链接到某个先前的节点。
Now I guess that you have defined two structures (Struct, Class or whatever depending on the language you're using). 现在,我猜您已经定义了两个结构(Struct,Class或任何其他类型,具体取决于您使用的语言)。 So lets say you have
Node_s
defined as a node with only a next
pointer, and Node_d
with both a next
and a prev
pointer. 因此,可以说你有
Node_s
定义为只有一个节点next
指针, Node_d
同时具有next
和prev
指针。 ( Node_d
may inherite from Node_s
so you just have to add the prev
attribute in the child class). (
Node_d
可以从Node_s
继承,因此您只需要在子类中添加prev
属性即可)。 Knowing this, the code above should be doing what you need: 知道了这一点,上面的代码应该可以满足您的需求:
function do_it(my_LinkedList linkedList){ 函数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
This previous code should be doing what you need. 前面的代码应该可以满足您的需求。 I wrote the answer in some kind of pseudo-java code so if you're not familiar with Java or don't understand what my pseudo-code does, please let me know.
我用某种伪Java代码编写了答案,所以如果您不熟悉Java或不了解我的伪代码做什么,请告诉我。 Anyway, the idea of my code may present some troubles depending on the language you're working with, so you'll have to adapt it.
无论如何,我的代码的想法可能会遇到麻烦,具体取决于您使用的语言,因此您必须对其进行调整。
Note that at the end of the execution of this program, your data structure won't be a singly linked list, and neither a double one, since you'll have linkedList.length() - 1
nodes linked in a signly way but the middle one will have two links. 请注意,在该程序执行结束时,您的数据结构将不是一个单链表,也不是一个双链表,因为您将拥有
linkedList.length() - 1
节点以一种有符号的方式链接,但是中间一个将有两个链接。
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.