get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。 addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。 addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。 addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
方式一:单链表实现
1 2 3 4 5 6 7
publicclassListNode{ int val; ListNode next; ListNode(int x) { val = x; } } //声明结点
1 2 3 4 5 6 7
int size; ListNode head; //sentinel node as pseudo-head publicMyLinkedList(){ size = 0; head = new ListNode(0); } } //声明链表,用哨兵做伪头,这样确保链表中节点永远不为空
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; //与删除不同,如果要获取指定索引处的节点,必须前进index+1步 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; //从头开始找给定索引处的前一个元素pred,
// 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; //找到的是要删除节点的前一个节点
publicclassListNode{ int val; ListNode next; //后继结点 ListNode prev; //前驱节点 ListNode(int x) { val = x; } }
classMyLinkedList{ int size=0; // 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; } //先找到待插入元素的前驱与后继,然后在进行节点指向的变更 // insertion itself ++size; //注意长度的更新 ListNode toAdd = new ListNode(val); toAdd.prev = pred; toAdd.next = succ; pred.next = toAdd; succ.prev = 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;
// 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; }