链表
前面学习的线性数据结构:
动态数组
栈
队列
底层都是依托静态数组:靠resize解决固定容量的问题。
链表
节点的数据结构
//节点的数据结构
private class Node{
private T val;//数据内容
private Node next;//指向下个节点的引用
Node(T val){
this.val = val;
this.next = null;
}
@Override
public String toString() {
return val.toString();
}
}
构建链表
//构建链表
private Node head;//头结点
private int size;//链表中元素的个数
public MyLink(){
head = null;
}
判断链表是否为空
//判断链表是否为空
public boolean isEmpty(){
return this.size == 0;
}
获取链表中节点的个数
//获取链表中节点的个数
public int getSize(){
return this.size;
}
在尾部添加节点
//在尾部添加节点
public void addTail(T val){
Node node = new Node(val);
if(head == null){
head = node;
}else {
Node curNode = head
while (curNode.next!=null){
curNode = curNode.next;
}
curNode.next = node;
}
}
在头部添加节点
//在头部添加节点
public void addHead(T val){
Node node = new Node(val);
node.next = head;
head = node;
}
在任意位置添加
//在任意位置添加
public void add(T val,int index){
Node node = new Node(val);
Node preNode = head;
if(head == null){
head = node;
return;
}
if(index==0){//原因是head没有头结点
node.next = head;
head = node;
return;
}
for(int i=0;i<index-1;i++){
preNode = preNode.next;
}
node.next = preNode.next;
preNode.next = node;
}
完整代码
package subject.lesson03;
public class MyLink<T> {
//节点的数据结构
private class Node{
private T val;//数据内容
private Node next;//指向下个节点的引用
Node(T val){
this.val = val;
this.next = null;
}
@Override
public String toString() {
return val.toString();
}
}
//构建链表
private Node head;//头结点
private int size;//链表中元素的个数
public MyLink(){
head = null;
}
//判断链表是否为空
public boolean isEmpty(){
return this.size == 0;
}
//获取链表中节点的个数
public int getSize(){
return this.size;
}
//在尾部添加节点
public void addTail(T val){
Node node = new Node(val);
if(head == null){
head = node;
}else {
Node curNode = head
while (curNode.next!=null){
curNode = curNode.next;
}
curNode.next = node;
}
}
//在头部添加节点
public void addHead(T val){
Node node = new Node(val);
node.next = head;
head = node;
}
//在任意位置添加
public void add(T val,int index){
Node node = new Node(val);
Node preNode = head;
if(head == null){
head = node;
return;
}
if(index==0){//原因是head没有头结点
node.next = head;
head = node;
return;
}
for(int i=0;i<index-1;i++){
preNode = preNode.next;
}
node.next = preNode.next;
preNode.next = node;
}
}
删除节点
//删除头结点
public T removeFirst(){
return remove(0);
}
//删除尾节点
public T removeLast(){
return remove(this.size-1);
}
//根据索引删除节点
public T remove(int index){
if(index>=this.size||index<0){
throw new IllegalArgumentException("index is error");
}
Node dummyHead = new Node(null);//虚拟头结点
dummyHead.next = head;
Node preNode = dummyHead;
for(int i=0;i<index;i++){
preNode = preNode.next;
}
T result = preNode.next.val;
preNode.next = preNode.next.next;
this.size--;
head = dummyHead.next;
return result;
}