在链接列表的开头插入

时间:2017-01-23 12:32:53

标签: java singly-linked-list

我是数据结构的初学者。我试图在链表的开头插入一个新节点。但该节点根本没有插入。问题只出现在开头的插入中。 请帮我 这是我的代码

public interface IRepository<T> where T: class
{
    IEnumerable<T> GetAll();
    T Get(long id);
    void Create(T item);
    void Update(T item);
    void Delete(T item);
    void Save();
}

public interface IIdentity
{
    long Id { get; set; }
}

public class BinaryFileRepository<T> : IRepository<T>
    where T : class, IIdentity
{
    private string fileName;
    private BinaryFormatter binaryFormatter;
    private List<T> items;

    public string FileName
    {
        get
        {
            return fileName;
        }
    }

    public BinaryFileRepository(string fileName)
    {
        this.fileName = fileName;
        binaryFormatter = new BinaryFormatter();

        if (File.Exists(fileName))
        {
            using (var fileStream = new FileStream(fileName, FileMode.Open))
            {
                items = (List<T>)binaryFormatter.Deserialize(fileStream);
            }
        }
        else
        {
            items = new List<T>();
        }
    }

    private long GetNextId()
    {
        return items.Any() ? items.Max(e => e.Id) + 1 : 1;
    }

    public void Create(T item)
    {
        if (item.Id == default(long))
        {
            item.Id = GetNextId();
        }
        else if (items.Any(e => e.Id == item.Id))
        {
            throw new ArgumentException("Duplicate item Id.");
        }

        items.Add(item);
    }
    public void Delete(T item)
    {
        if (items.Any(e => e.Id == item.Id))
        {
            items.Remove(item);
        }
    }
    public T Get(long id)
    {
        return items.FirstOrDefault(e => e.Id == id);
    }
    public IEnumerable<T> GetAll()
    {
        return items;
    }
    public void Save()
    {
        using (var fileStream = new FileStream(fileName, FileMode.Create))
        {
            binaryFormatter.Serialize(fileStream, items);
        }
    }
    public void Update(T item)
    {
        var listId = items.Where(e => e.Id == item.Id).Select((e, i) => i).First();
        items[listId] = item;
    }
}

提前致谢

2 个答案:

答案 0 :(得分:1)

首先,我强烈建议您重命名课程。 Java类应始终以大写字母开头(上面的驼峰案例)。并且变量和方法应该总是较低的驼峰情况(例外:静态最终变量通常都是全部大写)。

现在回答您的问题:您的错误在于:在您的方法内部,如果为赋予方法的head变量分配新值,则该更改仅影响变量head给予方法(仅在方法范围内)。如果要更改实际的head变量,则需要将新值直接分配给类head变量。

根据您的使用情况,有3种解决方案:

  1. 您需要LinkedList实现的多个实例:
    • 将方法insertBegindisplay更改为非静态。
    • 删除方法的第一个参数,因为它们现在可以访问类的变量head
  2. 您只需要一个LinkedList实现的实例(不是一个很好的解决方案):
    • 在班级static
    • 中设置您的头部变量
    • 删除方法的第一个参数,因为它们现在可以访问类的变量head
  3. 您希望保留变量/方法的静态/非静态模式(无论出于何种原因):
    • 更改head变量的行为:它现在从不存储实际数据,而是将实际头部(带数据)存储为nextNode变量。
    • display现在始终从head.nextValue
    • 开始阅读
    • insertBegin现在不必覆盖实际的头部变量。它只需要将nextNode变量设置为新头
  4. 如果您愿意,我可以举例说明其中一个案例。我只是不想把它们写出来让你自己弄清楚。

    如果您想提高Java技能,我还建议您查看变量和方法的各种可见性选项(私有,受保护,公共,默认)

答案 1 :(得分:0)

您的代码有很多错误。这不是人们编写链表的方式。请参阅@MichaelRitter的回答并进行更正。

使singlylinkedlist类中的所有函数都非静态,将link类移到singlylinkedlist类之外,并将main()方法写在singlylinkedlist之外的另一个类中}类。

就您的insertbegin()方法而言,首先需要将其设为非静态方法。此外,您只需要接受要在开头插入的函数参数中的整数值;取这个链表的头节点是没用的。此外,您需要在执行任何操作之前检查链接列表的头节点是否为null,否则您将获得NullPointerException

以下是insertbegin()类的singlylinkedlist方法的工作版本:

public void insertbegin(int x){
    link temp = new link(x);
    if(head == null)
        head = temp;
    else{
        link ts = head;
        head = temp;
        head.nextNode = ts;
    }
}

如果您想在名为1的单链接列表的开头插入link,可以将insertbegin()函数称为:

link.insertbegin(1);

我希望这会有所帮助。