[英]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.