谈谈个人对单向链表的理解(代码主要以Java形式展开)
声明:本篇文章只是笔者个人对链表的理解,其中的有些代码也是参考了其他的博主。如果有理解得不对的地方,希望大家能够指出,共同进步。**
单向链表
有过数据结构的基础的同学应该都知道,一个链表是由若干个节点组成的,而每一个节点由两部分组成,一部分是自己本身所储存的数据,另一部分则是指向下一个节点的节点对象。这刚听起来有点别扭,因为这就相当于每一个节点都存储另一个节点的对象,这个对象指向的是下一个节点。大概的原理图如下:
在这里我们把A(节点本身A的简称)称作头节点(链表里的基本操作差不多都是与头节点有关的),看了这个原理图以后我相大家都一目了然,在这张图里A的指向B,B指向C。链表就是由这样若干个节点组成的。
看到这里不知道大家有没有发现一个问题,那就是链表里的最后一个节点C里的对象指向哪里呢?
其实也很简单,就相当于如果只有一个节点的话,我们只需要让它直接指向null就好了。
明白了链表的组成是由节点组成的以后,我们就可以对其进行操作了。我们都知道,一般的链表都有最基本的增删查改操作。
那么往里面添加数据的话就是添加一个节点 (注意:在这里添加的顺序是从右往左进行的),在这里我们每添加一个节点就把头节点赋给新添加的那个节点。然后再把头节点的对象指向下一个节点。删除的话就更简单了,只需要把数据取出,然后再将头节点里的节点对象指向被删除节点的下一个节点…还有许多的操作都是在头节点上做文章的,在这里我就不一一赘述了。
话不多少,直接上代码:
public class SingleLinkList{ //新建一个单向链表类,里面含有头节点和节点个数2个属性,以及基本方法.
private LinkNode head; //头节点.
private int size; //表示节点的个数.
public SingleLinkList(){ //实例化链表后里面的属性都为初始属性.
size = 0;
head = null;
}
//链表里的每个节点的类
private class LinkNode{
private Object data; //每个节点的数据
private LinkNode next;//每个节点指向下一个节点的连接
}
public LinkNode(Object data){
this.data = data;
}
//在链表头添加数据.
public void add(Object obj){
//每添加一次数据就在里面实例化新的节点.
LinkNode newHead = new LinkNode(obj);
if(size == 0){
head = newHead;//创建第一个节点当作头节点,且next指向null.
head.data = obj; //将需要传入的数据赋给新建的第一个节点data.
}else
{
//新节点的next指向上一个节点,并且将新节点作为节点头(注意:添加的顺序是从后向前的),数据传入新的头节点内.
newHead.next = head;
newHead.data = obj;
head = newHead;
}
size++;
// return obj;
}
//在链表头删除数据.
public void removeHead(){
Object obj = head.data;
head = head.next;
System.out.println("在表头里被移除的数据为:"+obj);
size--;
}
//在链表中查找指定元素,找到了返回节点LinkNode,找不到返回null.
public LinkNode find(Object obj){
LinkNode current = head;
int time = size;
if(size == 0){
return null;
}
else{
for(int i = time;i>0;i--){
if(current.data != obj){
current = current.next;
}else
break;
}
return current;
}
}
//删除在链表内指定的内容
public void remove(int t){
LinkNode removenode = head;
LinkNode keepnode = head.next;
int time = size;
if(t != time) //如果删除的是第一个头节点
{
for(int i = time;i > 0;i--) //从头节点开始循环遍历,判断是否是删除的节点
{
if(i!=t)
{
keepnode = keepnode.next;
removenode = removenode.next;
}
else
Object obj = removenode.data ;
keepnode.next = removenode.next;
}
}
else
{
Object obj = keepnode.data;
keepnode = removenode;
}
System.out.println("被移除的数为:" + obj);
size--;
}
//显示链表里的所有信息
public void display(){
LinkNode temphead = head;
int tempSize = size;
if(tempSize == 0){
System.out.println("[ ]");
}else
if(tempSize == 1)
System.out.println("["+temphead.data+"]");
else{
while(tempSize>0)
{
if(temphead.next == null) //如果指向的下一个节点为null时.
{
System.out.println("["+temphead.data+"]");
}else
System.out.println("["+temphead.data+"]->");
temphead = temphead.next ;
tempSize --;
}
}
}
//获取节点的个数(链表的大小)
public int getsize(){
return size;
}
}