在单链接列表中添加双链表单节点

时间:2016-02-15 19:23:23

标签: java c++ algorithm data-structures linked-list

单独链接列表:1 -> 2 -> 3 -> 4 -> 5 -> null
将中间元素修改为双重链接列表节点
这里的中间元素是3
3 -> next应指向4
3 -> prev应指向1

任何人都可以建议如何做到这一点?面试官给了我提示use interface。但我无法弄清楚如何。
我必须迭代这个链表并打印所有节点,当它到达中间时,打印next和prev指向的位置,然后打印到列表的末尾。
Expected output1, 2, Middle: 3, Prev: 1, Next: 4, 5

我在添加中间节点时遇到问题。

3 个答案:

答案 0 :(得分:1)

通过定义,单链接列表仅由单链接节点组成,双链接仅由双链接节点组成。除此以外。它既不是。

通过定义双链表的字段<html lang="en"> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function createAjaxRequestObject() { var xmlhttp; if(window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } // Create the object return xmlhttp; } function AjaxPost(ajaxURL, parameters, onComplete) { var http3 = createAjaxRequestObject(); http3.onreadystatechange = function() { if(http3.readyState == 4) { if(http3.status == 200) { if(onComplete) { onComplete(http3.responseText); } } } }; // Create parameter string var parameterString = ""; var isFirst = true; for(var index in parameters) { if(!isFirst) { parameterString += "&"; } parameterString += encodeURIComponent(index) + "=" + encodeURIComponent(parameters[index]); isFirst = false; } // Make request http3.open("POST", ajaxURL, true); http3.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http3.send(parameterString); } function completedAJAX(response) { alert(response); } function testPass() { var parameters = { "uname" : document.getElementById("uname").value, "passwd" : document.getElementById("passwd").value }; AjaxPost("authenticate.php", parameters, completedAJAX); } </script> </head> <body> <p> <form id="login"> <strong>Login</strong><br/><br/> Username :<br/><input type="text" name="uname" id="uname" /><br/> Password :<br/><input type="password" name="passwd" id="passwd" /><br/><br/> <div id="message" style="color:red;"></div> <br/><button type="button" value="Submit" onclick="testPass();">Sign In</button> </form> </p> </body> </html> 必须指向前一个元素。

无论你应该建造什么。它没有明确规定。所以,如果你在接受采访时真的被问过这个问题(并没有误解这个问题 - 也许他想让你指出ghis 违反界面?)这就是代码恐怖故事{ {3}} - “无能的访调员”部分。

答案 1 :(得分:1)

所以,这&#34; 有效&#34;但如果预计会在面试时回答这个问题,那就太多了。

<强>链表

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());
        }

    }
}

答案 2 :(得分:0)

如果你还没有,你最好定义一个lenght()函数,这样一个链表可以知道它有多少个节点。

由于Cereal_Killer对此答案的先前版本的响应,我注意到该列表首先是单链表,您只需将中间节点链接到下一个节点和某个先前节点。

现在我猜你已经定义了两个结构(结构,类或其他任何取决于你正在使用的语言)。因此,假设您将Node_s定义为仅包含next指针的节点,并将Node_d定义为nextprev指针。 (Node_d可以继承自Node_s,因此您只需在子类中添加prev属性即可。知道这一点,上面的代码应该做你需要的:

function do_it(my_LinkedList linkedList){

    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个节点一个明显的方式,但中间的将有两个链接。

希望这有帮助。