一、基本理论
单向链表是最简单、最基础的链表,它的结点(Node)分成两个部分,第一部分存储结点的数据信息(data),第二部分存储指向下一个结点(next)的地址信息。最后一个结点指向空地址(null),单向链表的示意图如下所示:
二、基本操作
1、链表的构造:这里设置两个类,其中一个是结点的类,成员变量:data、next,另外一个类的成员变量:结点类型的head、链表的实际大小、链表最大容量的大小。
代码演示:
class Node<T>{
public T vlaue;
public Node next;
public Node(){ //申请头结点
next=null;
}
public Node(T value){
this.vlaue=value;
this.next=null;
}
public T getVlaue() {
return vlaue;
}
public void setVlaue(T vlaue) {
this.vlaue = vlaue;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
class Linklist<T>{
public Node head;
public Linklist(){
head=new Node();
}
}
2、插入元素:头插、尾插、按照位置插入
代码演示:
public void addHead(T value){//头插法
Node newNode=new Node(value);
Node p=head; //代表头部结点
newNode.next=p.next;//先拉右边的 p.next代表头结点所指向的下一个结点
head.next=newNode;//再拉左边的 head.next代表头结点的next域
size++;
}
代码演示:
public void addTail(T value){//尾插法
Node newNode=new Node(value);
Node p=head;
while(p.next!=null){
p=p.next;
}
p.next=newNode;
newNode.next=null;
size++;
}
代码演示:
public void addPos(int pos,T value){//按位置插值
Node newNode=new Node(value);
Node p=head;
int size=getLength();
if(pos<0 || pos>size){
System.out.println("插入的位置不合法!");
return ;
}
int count=0;
while(p.next!=null){
if(count==pos){
Node q=p.next;
p.next=newNode;
newNode.next=q;
}
count++;
p=p.next;
}
size++;
}
3、删除操作:头删、尾删、任意的位置进行删除
代码演示:
public void removeHead(){//删除头部结点
int size=getLength();
if(size==0){
throw new RuntimeException();
}else{
head=head.next;
}
size--;
}
代码演示:
public void removeTail(){//删除尾部结点
int size=getLength();
if(size==0){
return ;
}
Node p=head; //头结点
Node q=p.next; //头结点的下一个结点 意味着当q达到尾结点的时候,p就是尾结点的前驱!
while(q.next!=null){
q=q.next;
p=p.next;
}
p.next=null;
q.vlaue=null;
size--;
}
代码演示:
public void removePos(int pos){//删除任意位置的结点
int size=getLength();
if(size==0){
return ;
}
if(pos<0 || pos>size){
System.out.println("要删除的位置不合法!");
}
int count=0;
Node p=head;
while(p.next!=null){
if(count==pos){
Node q=p.next; //刚开始将它放在外面,借助它向前运行,以此将P作为找到位置的前驱,异常
p.next=p.next.next;// p.next=q.next.next;总是出现空指针异常!
q.next=null;
q.vlaue=null;
return ;
}
count++;
p=p.next;
}
size--;
}
代码演示:根据指定的元素进行删除:
public void removeValue(T value) {
int size = getLength();
boolean b = contain(value);
if (b == false || size == 0) {
return;
}
Node e = find(value);
Node p = e.next;
e.next = e.next.next;
p.vlaue = null;
size--;
}
3、查找元素
代码演示如下:
public boolean contain(T value){//查找指定的元素
Node p=head;
for(;p.next!=null;p=p.next){//最后一个元素无法遍历到,因为最后一个结点的next域是空的。
if(p.vlaue==value){
return true;
}
}if(p.vlaue==value){//在上述循环跳出来,也就是最后一个结点的next域为空时再进行判断
return true;
}
return false;
}
public Node find(T value){ //找到value的值,并返回前驱!
boolean b=contain(value);
int size=getLength();
if(b==false || size==0){
return null;
}
for(Node p=head;p.next!=null;p=p.next){
if(p.next.vlaue==value){
return p;
}
}
return null;
}