//增加:分为头插尾插和中间插入 //头部添加 publicvoidaddFirst(T x){ Node node = new Node(x); node.next = head; head = node; size++; }
//尾部插入 publicvoidaddLast(T x){ addMid(x, size); }
//中间插入 publicvoidaddMid(T x, int index){ if (index < 0 || index > size) { thrownew IllegalArgumentException("插入位置错误"); } if (index == 0) { addFirst(x); } Node pre = head; for (int i = 0; i < index - 1; i++) { pre = pre.next; } Node node = new Node(x); node.next = pre.next; pre.next = node; size++; }
//以上是基于索引的插入 //虚拟头节点的插入,基于插入元素 publicvoidvirAdd(T tag, T x){ Node dummy = new Node(null, head); Node cur = dummy; Node node = new Node(x); while (cur.next != null) { if (cur.next.val.equals(tag)) { node.next = cur.next; cur.next = node; size++; break; } else cur = cur.next; } head = dummy.next; }
//采用虚拟头节点的删除 publicvoiddelete(T x){ Node dummy = new Node(null, head); Node cur = dummy; while (cur.next != null) { if (cur.next.val.equals(x)) { cur.next = cur.next.next; size--; } else cur = cur.next; } head = dummy.next; }
//删除头部元素尾部元素和不采用虚拟节点 public T removeFirst(){ if (head == null) { System.out.println("没有元素可以删除"); returnnull; } Node del = head; head = head.next; del.next = null; size--; return (T) del.val; }
public T removeLast(){ if (head == null) { System.out.println("没有元素可以删除"); returnnull; } if (size == 1) { return removeFirst(); } Node pre = head; Node cur = head; while (cur.next != null) { pre = cur; cur = cur.next; } pre.next = cur.next; size--; return (T) cur.val; }
publicvoidremove(T x){ if (head == null) { System.out.println("没有元素可以删除"); return; } while (head != null && head.val.equals(x)) { head = head.next; size--; } Node cur = head; while (cur != null && cur.next != null) { if (cur.next.val.equals(x)) { cur.next = cur.next.next; size--; } else cur = cur.next; } }
//修改 publicvoidupdate(T tag, T val){ if (head == null) { System.out.println("链表为空"); return; } Node cur = head; while (cur != null) { if (cur.val == tag) { cur.val = val; // cur = cur.next; } cur = cur.next; } }
//查找 publicbooleanquery(T x){ Node cur = head; while (cur != null) { if (cur.val.equals(x)) { returntrue; } else cur = cur.next; } returnfalse; }
publicvoidshow(){ if (head == null) { System.out.println("链表为空,无法遍历"); } Node cur = head; while (cur != null) { System.out.println(cur.val); cur = cur.next; } } }
相关题目
1.LC707-设计链表
1 2 3 4 5 6
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。 addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。 addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。 addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
classMyLinkedList{ classNode{ publicint val; public Node next; publicNode(int val){ this.val=val; } } publicint size;//代表链表的长度 public Node head;//链表的头节点,注意不是虚拟节点,默认为null,若要采用虚拟节点,自行构造器中赋值 /** Initialize your data structure here. */ publicMyLinkedList(){ } //注意这里的index是从零开始的,后面每个方法都要注意节点的索引 /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ publicintget(int index){ if(index<0||index>size-1)return -1; Node res=head; for(int i=0;i<index;i++){ res=res.next; } return res.val; } /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ publicvoidaddAtHead(int val){ Node node=new Node(val); node.next=head; head=node; size++; } /** Append a node of value val to the last element of the linked list. */ publicvoidaddAtTail(int val){ Node node=new Node(val); Node tmp=head; if(head==null){ head=node; size++; return; } while(tmp.next!=null){ tmp=tmp.next; } tmp.next=node; size++; } /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ publicvoidaddAtIndex(int index, int val){ if(index<=0){ addAtHead(val); size++; return; } if(index>size)return; Node pre=head; Node tmp=new Node(val); for(int i=0;i<index-1;i++){ pre=pre.next; } tmp.next=pre.next; pre.next=tmp; size++; } /** Delete the index-th node in the linked list, if the index is valid. */ publicvoiddeleteAtIndex(int index){ if(index<0||index>size-1)return; Node pre=head; if(index==0){ head=head.next; size--; return; } for(int i=0;i<index-1;i++){ pre=pre.next; } pre.next=pre.next.next; size--; } }
/** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList obj = new MyLinkedList(); * int param_1 = obj.get(index); * obj.addAtHead(val); * obj.addAtTail(val); * obj.addAtIndex(index,val); * obj.deleteAtIndex(index); */
publicclassListNode{ int val; ListNode next; ListNode(int x) { val = x; } }
classMyLinkedList{ int size; ListNode head; // sentinel node as pseudo-head publicMyLinkedList(){ size = 0; head = new ListNode(0); }
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ publicintget(int index){ // if index is invalid if (index < 0 || index >= size) return -1;
ListNode curr = head; // index steps needed // to move from sentinel node to wanted index for(int i = 0; i < index + 1; ++i) curr = curr.next; return curr.val; }
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ publicvoidaddAtHead(int val){ addAtIndex(0, val); }
/** Append a node of value val to the last element of the linked list. */ publicvoidaddAtTail(int val){ addAtIndex(size, val); }
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ publicvoidaddAtIndex(int index, int val){ // If index is greater than the length, // the node will not be inserted. if (index > size) return;
// [so weird] If index is negative, // the node will be inserted at the head of the list. if (index < 0) index = 0;
++size; // find predecessor of the node to be added ListNode pred = head; for(int i = 0; i < index; ++i) pred = pred.next;
// node to be added ListNode toAdd = new ListNode(val); // insertion itself toAdd.next = pred.next; pred.next = toAdd; }
/** Delete the index-th node in the linked list, if the index is valid. */ publicvoiddeleteAtIndex(int index){ // if the index is invalid, do nothing if (index < 0 || index >= size) return;
size--; // find predecessor of the node to be deleted ListNode pred = head; for(int i = 0; i < index; ++i) pred = pred.next;
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。 addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。 addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。 addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
publicclassListNode{ int val; ListNode next; ListNode prev; ListNode(int x) { val = x; } }
classMyLinkedList{ int size; // sentinel nodes as pseudo-head and pseudo-tail ListNode head, tail; publicMyLinkedList(){ size = 0; head = new ListNode(0); tail = new ListNode(0); head.next = tail; tail.prev = head; }
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ publicintget(int index){ // if index is invalid if (index < 0 || index >= size) return -1;
// choose the fastest way: to move from the head // or to move from the tail ListNode curr = head; if (index + 1 < size - index) for(int i = 0; i < index + 1; ++i) curr = curr.next; else { curr = tail; for(int i = 0; i < size - index; ++i) curr = curr.prev; }
return curr.val; }
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ publicvoidaddAtHead(int val){ ListNode pred = head, succ = head.next;
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ publicvoidaddAtIndex(int index, int val){ // If index is greater than the length, // the node will not be inserted. if (index > size) return;
// [so weird] If index is negative, // the node will be inserted at the head of the list. if (index < 0) index = 0;
// find predecessor and successor of the node to be added ListNode pred, succ; if (index < size - index) { pred = head; for(int i = 0; i < index; ++i) pred = pred.next; succ = pred.next; } else { succ = tail; for (int i = 0; i < size - index; ++i) succ = succ.prev; pred = succ.prev; }
/** Delete the index-th node in the linked list, if the index is valid. */ publicvoiddeleteAtIndex(int index){ // if the index is invalid, do nothing if (index < 0 || index >= size) return;
// find predecessor and successor of the node to be deleted ListNode pred, succ; if (index < size - index) { pred = head; for(int i = 0; i < index; ++i) pred = pred.next; succ = pred.next.next; } else { succ = tail; for (int i = 0; i < size - index - 1; ++i) succ = succ.prev; pred = succ.prev.prev; }