java单链表-带头结点和不带头结点单链表的简单实现

带头结点的单链表实现
public class LinkedList<T> {
private Entry<T> head, tail; //头指针,尾指针
private int size; //通过一个变量记录链表长度

public LinkedList() {
//生成一个头结点,让头指针和尾指针都指向它
head = tail = new Entry<T>(null);
size = 0;
}

public int size() {
return size;
}

public boolean isEmpty() {
return head.next == null; //当头结点的next为空,表明整个链表为空
}

public T get(int index) {
return current(index).element;
}

public T set(int index, T element) {
Entry<T> entry = current(index);
T oldVal = entry.element;
entry.element = element;
return oldVal;
}

//默认在原链表尾部添加新的结点
public boolean add(T element) {
Entry<T> newEntry = new Entry<T>(element);
tail.next = newEntry;//原链表尾指针的next指向新的结点
tail = newEntry;//尾指针向后移动一位,指向新的结点
size++;
return true;
}

public boolean add(int index, T element) {
//若索引值和链表长度一样,新结点添加到链表最后位置
if (index == size)
return add(element);

//得到索引index的前一个结点
Entry<T> preEntry = previous(index);
//新结点的next为preEntry的next指向的结点
Entry<T> newEntry = new Entry<T>(element, preEntry.next);
//preEntry的next指向新的结点
preEntry.next = newEntry;
size++;
return true;
}

public T remove(int index) {
//得到索引index的前一个结点
Entry<T> preEntry = previous(index);
T oldVal = preEntry.next.element;
//如果preEntry的next刚好是最后一个结点,修改tail为preEntry
if (preEntry.next == tail)
tail = preEntry;
preEntry.next = preEntry.next.next;
size--;
return oldVal;
}

public void clear() {
head.next = null;
tail = head;
size = 0;
}

public String toString() {
String result = "[";
Entry<T> entry = head.next;
while (entry != null) {
result += entry.element;
entry = entry.next;
if (entry != null)
result += ", ";
}
return result + "]";
}

//获得索引index对应的entry
public Entry<T> current(int index) {
checkIndexBounds(index);
Entry<T> entry = head.next;//从第一个结点开始遍历
int c = 0;
while (entry != null && c < index) {
entry = entry.next;
c++;
}
return entry;
}

//获得索引index-1对应的entry
public Entry<T> previous(int index) {
checkIndexBounds(index);
Entry<T> entry = head;//从头结点开始遍历,头指针指向头结点
int c = 0;
while (entry.next != null && c < index) {
entry = entry.next;
c++;
}
return entry;
}

private void checkIndexBounds(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("[index: " + index + ", size: "
+ size + "]");
}

//结点对象
private static class Entry<T> {
T element;
Entry<T> next;

public Entry(T element) {
this(element, null);
}

public Entry(T element, Entry<T> next) {
this.element = element;
this.next = next;
}
}
}


不带头结点的单链表实现
public class LinkedList<T> {
private Entry<T> head, tail;
private int size;

public LinkedList() {
head = tail = null;
size = 0;
}

public int size() {
return size;
}

public boolean isEmpty() {
return head == null; //头指针为空,表示整个链表为空
}

public T get(int index) {
return current(index).element;
}

public T set(int index, T element) {
Entry<T> entry = current(index);
T oldVal = entry.element;
entry.element = element;
return oldVal;
}

public boolean add(T element) {
Entry<T> newEntry = new Entry<T>(element);
if (head == null) //如果头指针为空,直接将新结点赋值给头指针和尾指针
head = tail = newEntry;
else {
tail.next = newEntry; //否则,尾指针的next指向新的结点,尾指针后移一位,指向新的结点
tail = newEntry;
}
size++;
return true;
}

public boolean add(int index, T element) {
//若索引值和链表长度一样,新结点添加到链表最后位置
if (index == size)
return add(element);

//获得索引值为index-1的结点
Entry<T> preEntry = previous(index);
Entry<T> newEntry = new Entry<T>(element);
if (preEntry == null) { //index=0 直接操作头指针
newEntry.next = head;
head = newEntry;
} else { //其他情况,用获得的前一个结点完成添加操作
newEntry.next = preEntry.next;
preEntry.next = newEntry;
}
size++;
return true;
}

public T remove(int index) {
//获得索引值为index-1的结点
Entry<T> preEntry = previous(index);
T oldVal;
if (preEntry == null) {//index=0 直接操作头指针
oldVal = head.element;
head = head.next;
} else { //其他情况,用获得的前一个结点完成移除操作
oldVal = preEntry.next.element;
//如果preEntry的next刚好是最后一个结点,修改tail为preEntry
if (tail == preEntry.next)
tail = preEntry;
preEntry.next = preEntry.next.next;
}
size--;
return oldVal;
}

public void clear() {
head = tail = null;
size = 0;
}

public String toString() {
String result = "[";
Entry<T> entry = head;
while (entry != null) {
result += entry.element;
entry = entry.next;
if (entry != null)
result += ", ";
}
return result + "]";
}

public Entry<T> current(int index) {
checkIndexBounds(index);
Entry<T> entry = head;
int c = 0;
while (entry != null && c < index) {
entry = entry.next;
c++;
}
return entry;
}

public Entry<T> previous(int index) {
checkIndexBounds(index);
if (index == 0) //索引为0 直接返回null,表明直接用头指针完成操作即可
return null;

Entry<T> entry = head;
int c = 0;
while (entry.next != null && c < index - 1) {
entry = entry.next;
c++;
}
return entry;
}

private void checkIndexBounds(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("[index: " + index + ", size: "
+ size + "]");
}

private static class Entry<T> {
T element;
Entry<T> next;

public Entry(T element) {
this(element, null);
}

public Entry(T element, Entry<T> next) {
this.element = element;
this.next = next;
}
}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值