java实现带头结点的单链表、不带头结点单链表、不带头单向循环链表、不带头双向链表的增删改查操作
程序员文章站
2022-03-15 17:30:20
...
带头结点的单链表
public class Entry<T extends Comparable<T>> {//自定义数据类型才需要重写compareTo方法
private T value;
private Entry<T> next;
public Entry(){//头结点
}
public Entry(T value){//其他结点
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Entry<T> getNext() {
return next;
}
public void setNext(Entry<T> next) {
this.next = next;
}
}
public class SingleLink<E extends Comparable<E>>{//带头结点
private Entry<E> head;
private Entry<E> tail;//想让时间复杂度降低,防止遍历导致时间复杂度大
public SingleLink(){
head = new Entry<>();
tail = head;
}
public void addHead(E value){
Entry<E> newEntry = new Entry<>(value);
newEntry.setNext(head.getNext());
head.setNext(newEntry);
}
public void addTail(E value){//时间复杂度可以达到O(1)
Entry<E> newEntry = new Entry<>(value);
tail.setNext(newEntry);
tail = newEntry;//更新尾节点
}
public void deleteHead(){
if(head.getNext()==null){//防止空指针异常
return;
}
Entry<E> p=head.getNext();
head.setNext(head.getNext().getNext());
// 防止内存泄漏
p.setValue(null);
p.setNext(null);
}
public void deleteTail(){//时间复杂度为O(n),无法达到O(1)
Entry<E> p=head;
if(p.getNext()==null){
return;
}
while(p.getNext().getNext()!=null){
p=p.getNext();
}
p.setNext(null);
//防止内存泄漏
p.getNext().setValue(null);
/**
* TODO:再次遍历,更新尾节点(这一步我没有写出来)
*/
}
public void deleteValue(E value){
Entry<E> p=head;
for(;p.getNext()!=null;p=p.getNext()){
if (p.getNext().getValue().compareTo(value)==0){//不建议用equals,假如传的是People类型(自定义数据类型),可能忘记重写equals方法
break;
}
}
Entry<E> q=p.getNext();
p.setNext(p.getNext().getNext());
//防止内存泄漏
q.setValue(null);
q.setNext(null);
}
}
不带头结点的单链表
public class SingleLinkNoHead<T extends Comparable<T>> {
public static class Entry<E extends Comparable<E>> {//改成public易于测试
public E value;
public Entry<E> next;
public Entry(E value) {
this.value = value;
}
public void setNext(Entry<E> next) {
this.next = next;
}
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
public Entry<E> getNext() {
return next;
}
}
private Entry<T> headEntry;
private Entry<T> tailEntry;
public SingleLinkNoHead() {
}
public void addHead(T value) {
Entry<T> newEntry = new Entry<>(value);
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
} else {
newEntry.next = headEntry;
headEntry = newEntry;
}
}
public void addTail(T value) {
Entry<T> newEntry = new Entry<>(value);
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
} else {
tailEntry.next = newEntry;
tailEntry = newEntry;
}
}
public void deleteHead() {
if (headEntry == null) {
return;
} else if (headEntry.next == null) {
headEntry = null;
tailEntry = null;
} else {
Entry<T> p = headEntry;
headEntry = headEntry.next;
p.value = null;
p.next = null;
}
}
private Entry<T> searchPrio() {//找尾节点前驱
for (Entry<T> p = headEntry; p != null; p = p.next) {
if (p.next == tailEntry) {
return p;
}
}
return null;
}
public void deleteTail() {
Entry<T> prio = searchPrio();
if (prio == null) {
return;
} else if (headEntry.next == null) {
headEntry.value = null;
headEntry = null;
tailEntry = null;
} else {
prio.next = null;
tailEntry.value = null;
tailEntry = prio;
}
}
不带头结点的单向循环链表
public class CircleSingleLink<T> {
private static class Entry<E> {
private Entry<E> next;
private E value;
public Entry(E value) {
this.value = value;
next = this;
}
}
private Entry<T> headEntry;
private Entry<T> tailEntry;
public CircleSingleLink() {
}
public void addHead(T value) {
Entry<T> newEntry = new Entry<>(value);
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
} else {
//1
newEntry.next = headEntry;
//2
headEntry = newEntry;
//3
tailEntry.next = headEntry;
}
}
public void addTail(T value) {
Entry<T> newEntry = new Entry<>(value);
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
} else {
tailEntry.next = newEntry;
newEntry.next = headEntry;
tailEntry = newEntry;
}
}
public void deleteHead() {
if (headEntry == null)
return;
//防止内存泄漏
headEntry.value = null;
//只有一个节点
if (headEntry.next == headEntry) {
headEntry = null;
tailEntry = null;
} else {
tailEntry.next = headEntry.next;
headEntry = headEntry.next;
}
}
public void deleteTail() {
if (headEntry == null) {
return;
} else if (headEntry.next == headEntry) {
headEntry = null;
tailEntry = null;
} else {
Entry<T> p = headEntry;
for (; p != null; p = p.next) {
if (p.next == tailEntry) {
break;
}
}
p.next = headEntry;
tailEntry.next = null;
tailEntry.value = null;
tailEntry = p;
}
}
}
不带头结点的双向链表
public class DoubleLink<T> {
public static class Entry<E> {
private E value;
private Entry<E> next;
private Entry<E> prev;
public Entry(E value) {
this.value = value;
}
}
private Entry<T> headEntry;
private Entry<T> tailEntry;
public DoubleLink() {
}
public void addHead(T value) {
Entry<T> newEntry = new Entry<>(value);
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
} else {
newEntry.next = headEntry;
headEntry.prev = newEntry;
headEntry = newEntry;
}
}
public void addTail(T value) {
Entry<T> newEntry = new Entry<>(value);
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
} else {
tailEntry.next = newEntry;
newEntry.prev = tailEntry;
tailEntry = newEntry;
}
}
public void deleteHead() {
if (headEntry == null) {
return;
} else if (headEntry.next == null) {
headEntry = null;
tailEntry = null;
} else {
headEntry.value = null;
headEntry.next.prev = null;
headEntry = headEntry.next;
}
}
public void deleteTail() {
if (headEntry == null) {
return;
} else if (headEntry.next == null) {
headEntry = null;
tailEntry = null;
} else {
Entry<T> p =headEntry;
for(;p!=null;p=p.next){
if(p.next==tailEntry){
break;
}
}
p.next=null;
tailEntry.value=null;
tailEntry.prev=null;
tailEntry=p;
}
}
}