单链表的实现需要定义两个类,一个是Node类,存储了节点的数据值以及后继节点的引用。另外一个类就是list,用于存储这些Node节点。单链表的插入和删除操作有两种方法:头结点插入(删除)和末节点插入(删除)。无论是头结点插入还是末节点插入,需要考虑的特殊情况是如果链表是空的话,方法适合也适合。同时,如果链表是空的话,需要更新tail的值为指向插入的节点。无论是头结点删除还是末节点删除,首先检测链表大小,如果为空的话,输出提示信息,不做其他操作。另外还需要考虑链表只有一个节点的情况。总而言之,头结点的插入和删除操作,时间复杂度均是O(1),而末节点的插入操作是O(1),删除操作是O(n)。相比而言,头结点插入和删除效率较高。具体实现代码如下:
1 /** 2 * Created by hfz on 2016/8/2. 3 * 单链表的实现需要定义两个类,一个是Node类,存储了节点的数据值以及后继节点的引用。 4 * 另外一个类就是list,用于存储这些Node节点。 5 */ 6 public class list { 7 private Node head=new Node();//指向链表首节点引用,虽然head中各元素为null,不过head不为null,是一个对象了 8 private Node tail=new Node();//指向链表末节点引用 9 private int size=0; 10 /* 11 无论是头结点插入还是末节点插入,需要考虑的特殊情况是如果链表是空的话,方法适合也适合。同时,如果链表是空的话,需要更新 12 tail的值为指向插入的节点。 13 无论是头结点删除还是末节点删除,首先检测链表大小,如果为空的话,输出提示信息,不做其他操作。另外还需要考虑链表只有一个节点 14 的情况。 15 总而言之,头结点的插入和删除操作,时间复杂度均是O(1),而末节点的插入操作是O(1),删除操作是O(n)。 16 相比而言,头结点插入和删除效率较高。 17 */ 18 19 /* 20 头结点插入: 21 1.将首节点引用赋值给插入节点的next域。 22 2.将插入节点的引用赋值给首节点。 23 这种方法在链表为空是依然适用,只不过需要设置tail值为插入节点的引用。 24 操作在O(1)时间内完成 25 */ 26 //头结点插入 27 public void addAtHead(Node node){ 28 node.setNext(head);//next域指向当前首节点 29 head=node;//链表的head指向新插入的节点 30 if(size++==0){//如果当前是空链表,更新末节点引用。 31 tail=node; 32 } 33 } 34 /* 35 头结点删除:只需要将头指针指向的节点的next域赋值给头指针即可。 36 即使单链表只有一个节点,这种方法依然正确,只不过,这种情况下需要设置tail为null 37 操作在O(1)时间内完成 38 */ 39 //头结点删除 40 public void deleteAtHead(){ 41 if(size>0) 42 { 43 head = head.getNext(); 44 if (size-- == 1) { 45 tail = new Node(); 46 } 47 } 48 else{ 49 System.out.println("链表为空,不能删除节点"); 50 } 51 } 52 /* 53 末节点插入 54 */ 55 public void addAtTail(Node node){ 56 node.setNext(null); 57 tail.setNext(node);// Node tail=new Node();必须使用这种形式给tail赋初值,虽然tail中各内容是null,不过tai已经是对象 58 //可以调用setNext()方法。如果是以Node tail=null,就会抛出空指针异常“.NullPointerException”,因为tail并不是对象, 59 // 不能调用方法 60 tail=node; 61 if(size++==0){ 62 head=node; 63 } 64 } 65 /* 66 末节点删除 67 */ 68 public void deleteAtTail(){ 69 Node tempNode=head; 70 Node preNode=new Node(); 71 if(size>0){ 72 while (!tempNode.equals(tail)){ 73 preNode=tempNode; 74 tempNode=tempNode.getNext(); 75 } 76 preNode.setNext(null); 77 tail=preNode; 78 if(size--==1){ 79 head=new Node(); 80 } 81 } 82 else { 83 System.out.println("链表为空,不能删除节点"); 84 } 85 } 86 //测试代码 87 public static void main(String[] args){ 88 list ls=new list(); 89 ls.addAtTail(new Node("D1",null)); 90 ls.addAtHead(new Node("A", null)); 91 ls.addAtHead(new Node("B", null)); 92 ls.addAtHead(new Node("C", null)); 93 ls.deleteAtHead(); 94 ls.deleteAtHead(); 95 ls.deleteAtHead(); 96 ls.deleteAtHead(); 97 ls.deleteAtHead(); 98 ls.addAtTail(new Node("D1", null)); 99 ls.addAtTail(new Node("D2", null)); 100 ls.addAtTail(new Node("D3", null)); 101 ls.addAtTail(new Node("D4",null)); 102 ls.deleteAtTail(); 103 ls.deleteAtTail(); 104 System.out.println(); 105 } 106 } 107 class Node { 108 private Object ele; 109 private Node next; 110 public Node(){ 111 this(null,null); 112 } 113 public Node(Object ele,Node next){ 114 this.ele=ele; 115 this.next=next; 116 } 117 118 public Object getEle(){ 119 return ele; 120 } 121 public Object setEle(Object ele){ 122 Object oldEle=this.ele; 123 this.ele=ele; 124 return oldEle; 125 } 126 127 public Node getNext(){ 128 return next; 129 } 130 131 public void setNext(Node newNext){ 132 next=newNext; 133 } 134 }
时间: 2024-12-31 03:48:33