односвязный список в C # с использованием метода расширения - PullRequest
0 голосов
/ 11 марта 2019
  1. почему метод расширения не возвращает измененный узел в операциях вставки.
  2. Но он работает нормально во время создания связанного списка.
  3. Метод расширения должен возвращать измененный узел.
  4. Какой идеальный способ сделать это.
  5. IS метод расширения, хорошо работающий

Код следует

public class Node
{
    public Object Data { get; set; }
    public Node NextNode { get; set; }
}
public static class ListOperations
{
    public static void CreateLinkedList(this Node node, Object data)
    {
        if (node.Data == null)
        {
            node.Data = data;
        }
        else
        {
            Node newnode = new Node();
            newnode.Data = data;
            Node current = new Node();
            current = node;
            while (current.NextNode != null)
            {
                current = current.NextNode;
            }
            current.NextNode = newnode;
            node = current;
        }
    }
    public static void InsertNode(this Node node1, Object data, int position)
    {

        Node newnode = new Node();
        newnode.Data = data;
        if (position == 1)
        {
            newnode.NextNode = node1;
            node1 = newnode;

        }

    }
}
class Program
{
    static void Main(string[] args)
    {
        Node node = new Node();
        //random Singly LinkedList
        node.CreateLinkedList(10);
        node.CreateLinkedList(11);
        node.CreateLinkedList(12);
        node.CreateLinkedList(13);
        node.CreateLinkedList(14);
        node.CreateLinkedList(15);
        node.InsertNode(20, 1);// this method does not return node value what is inserted.


    }
}

1 Ответ

1 голос
/ 11 марта 2019

Есть много вещей, которые не так с вашим кодом, и мы можем разобраться с ними позже. Но давайте сначала ответим на ваши вопросы. Я буду немного буквальным и прямым, так как я не могу предположить, почему вы сделали это так, как это делается.

почему метод расширения не возвращает измененный узел в операциях вставки.

Поскольку ваш метод ничего не возвращает

Но это работало отлично во время создания связанного списка.

Да, поскольку этот код никогда не изменяет параметр this Node node

Метод расширения должен возвращать измененный узел.

Только если вы действительно вернете какие-либо данные из метода!

Какой идеальный способ сделать это.

см. Ниже

IS метод расширения, хорошо работающий

метод расширения по сравнению с чем? По сравнению с методом-участником, написанным аналогично, в случаях, относящихся к вашему примеру, не должно быть разницы в производительности

Идеальный способ сделать это:

Итак, обо всем по порядку: здесь нет необходимости писать метод расширения. Почему бы вам не написать обычный метод члена? Расширения обычно выполняются, когда класс, который вы хотите добавить, недоступен для редактирования напрямую, как правило, поскольку код принадлежит третьей стороне

Во-вторых, вы не совсем понимаете ссылки и то, как работает передача по значению. Сначала позвольте мне опубликовать лучший код, а затем объяснить его

public class Node {
    public object Data { get; set; }
    public Node NextNode { get; set; }

    public Node(object data) {
        Data = data;
    }

    public Node AppendNode(object data) {
        var newNode = new Node(data);

        var current = this;
        while (current.NextNode != null)
            current = current.NextNode;
        current.NextNode = newNode;

        return newNode;
    }

    public Node SetFirstNode(object data) {
        return new Node(data) { NextNode = this };
    }
}

class Program {
    static void Main(string[] args) {
        var linkedList = new Node(10);
        linkedList.AppendNode(11);
        linkedList.AppendNode(12);
        linkedList.AppendNode(13);
        linkedList.AppendNode(14);
        linkedList.AppendNode(15);
        linkedList = linkedList.SetFirstNode(20);

    }
}

Важные вещи, на которые следует обратить внимание с точки зрения вашего основного вопроса (почему вставка не сработала), заключается в том, что метод SetFirstNode фактически возвращает вновь созданный узел, а в Main мы переназначаем связанный список как таковой linkedList = linkedList.SetFirstNode(20);

Теперь вы можете написать статический метод и передать ref в связанный список, но, на мой взгляд, это не очень хорошая практика. Тем не менее, код будет выглядеть так:

public static class ListOperations {
    public static void InsertNode(ref Node linkedList, object data) {
        linkedList = new Node(data) { NextNode = linkedList };
    }
}

Помимо прочего, я называю объект node как linkedList, CreateLinkedList как AppendNode и InsertNode как SetFirstNode, чтобы вы могли лучше понять код.

Ниже приведен тот же код с общим аргументом вместо object Data и использованием правильного InsertNode метода

public class Node<T> {
    public T Data { get; set; }
    public Node<T> Next { get; set; }

    public override string ToString() {
        return Data.ToString();
    }

    public Node(T data) {
        Data = data;
    }

    public Node<T> AppendNode(T data) {
        var newNode = new Node<T>(data);

        var current = this;
        while (current.Next != null)
            current = current.Next;
        current.Next = newNode;

        return newNode;
    }

    /// <summary>
    /// Inserts a new node into the linkedlist as the desired position
    /// </summary>
    /// <param name="position">0-based index for the final position of new node</param>
    /// <param name="newNode">The newly created node containing data</param>
    /// <returns>returns the first node of the linkedlist</returns>
    public Node<T> InsertNode(T data, int position, out Node<T> newNode) {
        var current = this;
        position--;
        newNode = new Node<T>(data);
        if (position < 0) {
            newNode.Next = current;
            return newNode;
        }

        for (int i = 0; i < position; ++i)
            current = current.Next;
        newNode.Next = current.Next;
        current.Next = newNode;
        return this;
    }
}

class Program {
    static void Main(string[] args) {
        var linkedList = new Node<int>(10);
        linkedList.AppendNode(11);
        linkedList.AppendNode(12);
        linkedList.AppendNode(13);
        linkedList.AppendNode(14);
        linkedList.AppendNode(15);
        linkedList = linkedList.InsertNode(20, 0, out var newNode);
    }
}
...