catalogue
Design linked list
describe
Design the implementation of linked list. You can choose to use single linked list or double linked list.
A node in a single linked list should have two attributes: val and next. val Is the value of the current node, next Is a pointer / reference to the next node.
If you want to use a two-way linked list, you also need an attribute prev To indicate the previous node in the linked list.
It is assumed that all nodes in the linked list are 0-index.
Implement these functions in the linked list class:
- get(index): get the second index in the linked list index The value of the first node. Returns - 1 if the index is invalid.
- addAtHead(val): add a value of before the first element of the linked list val Node for. After insertion, the new node will become the first node in the linked list.
- addAtTail(val): set the value to The node of val is appended to the last element of the linked list.
- addAtIndex(index,val): the second index in the linked list index Add value before nodes val Node for. If index Equal to the length of the linked list, the node will be attached to the end of the linked list. If the index is greater than the length of the linked list, the node will not be inserted. If the index is less than 0, the node is inserted in the header.
- deleteAtIndex(index): if the index If the index is valid, the second index in the linked list will be deleted Index nodes.
Example
MyLinkedList linkedList = new MyLinkedList(); linkedList.addAtHead(1); linkedList.addAtTail(3); linkedList.addAtIndex(1,2); //The linked list becomes 1 - > 2 - > 3 linkedList.get(1); //Return 2 linkedList.deleteAtIndex(1); //Now the linked list is 1 - > 3 linkedList.get(1); //Return 3
Tips
- All val values are in [1, 1000] Within.
- The number of operations will be [1, 1000] Within.
- Do not use the built-in LinkedList library.
Single linked list:
The data structure of a single linked list is relatively simple, with only values and pointers to the next node.
When designing the single linked list, in order to make the deletion and insertion of the head node the same as other nodes, we introduce a virtual head node, and the real data node starts from the second node.
class MyLinkedList { private MyListNode head;//A virtual header node that points to the first data node private int len;//Store the length information of the linked list public MyLinkedList() { head = new MyListNode(); len = 0; } public int get(int index) { if (index<0||index>=len) return -1; MyListNode cur=head.next;//Start with the first data node for (int i = 0; i < index; i++) { cur=cur.next; } return cur.val; } public void addAtHead(int val) { addAtIndex(0,val); } public void addAtTail(int val) { addAtIndex(len,val); } public void addAtIndex(int index, int val) { if (index>len) return; if (index<0) index=0; MyListNode pre=head; for (int i = 0; i < index; i++) { pre=pre.next; } MyListNode node=new MyListNode(val);//Create a new node node.next=pre.next;//Inserts the current node into the location pre.next=node; len++;//Total length of linked list + 1 } public void deleteAtIndex(int index) { if (index<0||index>=len) return;//Cross border direct exit MyListNode pre=head; for (int i = 0; i < index; i++) { pre=pre.next; } pre.next=pre.next.next;//Delete node len--;//Total length of linked list - 1 } } class MyListNode { public int val; public MyListNode next; public MyListNode() { val = 0; next = null; } public MyListNode(int val) { this.val = val; } }
Double linked list:
The double linked list has one more pointer than the single linked list, pointing to the previous node, which will make the deletion and insertion operations easier.
class MyLinkedList { private MyListNode head; private MyListNode tail; private int len; public MyLinkedList() { head=new MyListNode(0); tail=new MyListNode(0); head.next=tail; tail.pre=head; len=0; } public int get(int index) { if (index<0 ||index>=len) return -1;//Cross border direct return - 1 MyListNode cur=head; if (index+1<len-index){//If the element is near the head node, it is traversed from scratch for (int i = 0; i < index+1; i++) cur=cur.next; }else{//If the element is near the tail node, the traversal starts from the tail cur=tail; for (int i = 0; i < len-index; i++) cur=cur.pre; } return cur.val; } public void addAtHead(int val) { MyListNode pre=head,first=head.next; //Add data to header MyListNode node=new MyListNode(val); node.pre=pre;node.next=first; pre.next=node;first.pre=node; len++; } public void addAtTail(int val) { MyListNode last=tail,pre=tail.pre; //Add data to tail MyListNode node=new MyListNode(val); node.pre=pre;node.next=last; pre.next=node;last.pre=node; len++; } public void addAtIndex(int index, int val) { if (index>len) return; if (index<0) index=0; MyListNode pre,cur; if (index+1<len-index){//If the element is near the head node, it is traversed from scratch pre=head; for (int i = 0; i < index; i++) pre=pre.next;//Traverse to the previous position to be inserted cur=pre.next;//Node location to insert }else{//If the element is near the tail node, the traversal starts from the tail cur=tail;//Node location to insert for (int i = 0; i < len-index; i++) cur=cur.pre; pre=cur.pre;//Previous position to insert } MyListNode node=new MyListNode(val); node.pre=pre;node.next=cur;//Insert the new node between pre and cur pre.next=node;cur.pre=node; len++; } public void deleteAtIndex(int index) { if (index<0 || index>=len) return;//Cross border direct return MyListNode pre,cur; if (index+1<len-index){//If the element is near the head node, it is traversed from scratch pre=head; for (int i = 0; i < index; i++) pre=pre.next;//Traverse to the previous location to be deleted cur=pre.next.next;//Deletes the next node of a node }else{//If the element is near the tail node, the traversal starts from the tail cur=tail;//The last node to be deleted for (int i = 0; i < len-index-1; i++) cur=cur.pre; pre=cur.pre.pre;//Previous location to delete } pre.next=cur;//Delete current node cur.pre=pre; len--; } } class MyListNode{ public int val;//The value stored by the node public MyListNode pre;//Points to the previous node of the current node public MyListNode next;//Points to the next node of the current node public MyListNode(int val){ this.val=val; } }