双向链表及循环链表
双向链表
双链表和单链表相比,多了一个指向尾指针(tail),双链表的每个结点都有一个头指针head和尾指针tail,双链表相比单链表更容易操作,双链表结点的首结点的head指向为null,tail指向下一个节点的tail;尾结点的head指向前一个结点的head,tail 指向为null,是双向的关系
双向链表代码
import java.util.Iterator;
public class TwoWayLink implements Iterable {
Node head = null;
Node tail = null;
int size;
class Node {
Node next = null;
Node previous = null;
int data;
public Node(int data) {
this.data = data;
}
@Override
public String toString() {
return "data:" + data;
}
}
public void addNode(int d) {
Node newNode = new Node(d);
if (head == null) {
head = newNode;
tail = newNode;
size = 1;
return;
}
Node tailTmp = tail;
tailTmp.next = newNode;
newNode.previous = tailTmp;
tail = newNode;
size++;
}
public Node getNode(int index) {
if (index == 0) {
return head;
}
if (index + 1 == size) {
return tail;
}
int i = 1;
Node curNode = head.next;
while (curNode != null) {
if (i == index) {
return curNode;
}
curNode = curNode.next;
i++;
}
return null;
}
public Node removeNode(Node remove) {
Node previous = remove.previous;
Node next = remove.next;
if (remove.equals(head)) {
next.previous = null;
head = next;
} else if (remove.equals(tail)) {
previous.next = null;
tail = previous;
} else {
previous.next = next;
next.previous = previous;
}
size--;
return remove;
}
public int size() {
return size;
}
@Override
public Iterator iterator() {
return new Iterator() {
int cursor;
int lastRet = -1;
@Override
public boolean hasNext() {
return cursor != size;
}
@Override
public Object next() {
lastRet = cursor;
cursor++;
return getNode(lastRet);
}
};
}
public static void main(String[] args) {
TwoWayLink twoWayLink = new TwoWayLink();
twoWayLink.addNode(1);
twoWayLink.addNode(2);
twoWayLink.addNode(3);
System.out.println(twoWayLink.size());
Iterator iterator = twoWayLink.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
循环链表
节点自身数值data以及所指向的下一个节点next
package circularLinkedList;
public class Node {
//元素类型为int的节点
private int data;
private Node next;
//定义构造器
public Node(int i, Node nt){
data = i;
next = nt;
}
public Node(int i){
this(i,null);
}
public Node(){
this(0,null);
}
//更改元素数值
public void setData(int i){
data = i;
}
//读取元素数值
public int getData(){
return data;
}
//更改元素的指向
public void setNext(Node nt){
next = nt;
}
//读取元素的指向
public Node getNext(){
return next;
}
关键要素是指定链表的头节点head、尾节点tail以及链表大小size;该数据结构支持在头部增加节点、在尾部增加节点,从头部删除节点及从尾部删除节点
package circularLinkedList;
public class Linkedlst {
private Node head;
private Node tail;
int size;
//构造器
public Linkedlst(){
tail = head = null;
size = 0;
}
//在链表头部增加节点
public void addHead(Node hd){
//如果使用该方法增加链表的第一个节点,则head=tail=hd,且next指向自身。
if(size==0){
hd.setNext(hd);
tail = head = hd;
size++;
}
else{
tail.setNext(hd);
hd.setNext(head);
head = hd;
size++;
}
}
//在链表尾部增加节点
public void addTail(Node tl){
//如果使用该方法增加链表的第一个节点,则tail=head= hd,且next指向自身。
if(size==0){
tl.setNext(tl);
tail = head = tl;
size++;
}
else{
tail.setNext(tl);
tl.setNext(head);
tail = tl;
size++;
}
}
//删除头部节点,被删掉的head将被自动回收
public void delHead(){
if(size>1){
head = head.getNext();
tail.setNext(head);
size--;
}
else if(size==1){
head = tail = null;
size--;
}
else{
System.out.println("There is no elements in the linked list.");
}
}
//删除尾部节点
public void delTail(){
if(size>1){
Node nd = new Node();
nd = head;
while(nd.getNext()!=tail){
nd = nd.getNext();
}
nd.setNext(head);
size--;
}
else if(size==1){
head = tail = null;
size--;
}
else{
System.out.println("There is no elements in the linked list.");
}
}
//打印全部节点
public void printList(){
Node nd = new Node();
nd = head;
try{
while(nd.getNext()!=head){
System.out.print(nd.getData());
System.out.print("->");
nd = nd.getNext();
}
System.out.print(nd.getData());
System.out.print("->");
System.out.print(head.getData());
}
catch(Exception e){
e.printStackTrace();
}
}
}