单链表算是最简单的数据结构了,但一般单链表都是用c的结构或者是c++来实现,今天我想尝试下用Java来实现单链表以及相关的几个算法。
一个单链表的节点属性主要由两部分组成,分别是数据和下一个节点的引用(这里仅讨论一般的单链表,不讨论双向链表、循环链表、双向循环链表等),实现代码如下:
private static class Node<T>{
T data;
Node<T> next;
Node(T data){
this.data = data;
this.next = null;
}
}
单链表的方法主要是增删查改,有点像对数据库的描述哈。
先说增,顾名思义,即增加节点。
实现代码:
//为空链表增加头结点
public void addHead(T point){
this.head = new Node<T>(point);
if(tail == null){
tail = head;
}
}
//为链表增加尾节点
public void addTail(T point){
tail = new Node<T>(point);
head.next = tail;
}
//插入新节点
public void insert(T point){
if(this.head == null){
addHead(point);
}
else if (this.tail == this.head){
addTail(point);
}
else
{
Node<T> preNode = this.tail;
Node<T> newNode = new Node<T>(point);
preNode.next = newNode;
this.tail = newNode;
}
}
/**
* 插入相应位置的节点
* @param point
* @param n
*/
public void insert(T point, int n){
Node<T> curr = this.head,prev = null;
Node<T> newNode = new Node<T>(point);
int i;
for(i=0;i<n;i++)
{
prev = curr;
curr = curr.next;
}
if(curr == this.head){
newNode.next = curr;
this.head = newNode;
}
else if(curr == this.tail){
curr.next = newNode;
this.tail = newNode;
}
else
{
prev.next = newNode;
newNode.next = curr;
}
}
删即删除节点,方法如图所示:
/**
* 删除节点
* @param point
*/
public void deleteNode(T point){
Node<T> curr = this.head,prev = null;
boolean suc = false;
while(curr != null){
if(curr.data == point){
if(curr == head) //delete the head Node
{
head = head.next;
suc = true;
return;
}
else if(prev == tail){ //delete the tail Node
prev.next =null;
this.tail = prev;
suc = true;
return;
}
else //delete the center node
{
prev.next = curr.next;
suc = true;
return;
}
}
prev = curr;
curr = curr.next;
}
if(suc == false){
System.out.println("The node is not exist!");
}
}
查和改可以放在一起说,因为改必须要用到查,查到相应的节点然后进行修改。
实现代码如下:
public Node<T> search(int n){
Node<T> q;
q = this.head;
for(int i = 0;i < n;i++){
q = q.next;
}
return q;
}
public void update(int n,T a){
Node<T> q;
q = this.search(n);
q.data = a;
}
单链表问题
- 逆置
思路:
逆置后原来的最后一个结点成为第一个结点,于是从第一个结点开始逐个修改每个结点的指针域进行逆置,且刚被逆置的结点总是新链表的第一个结点,故令head指向它。
public void contray(){
Node<T> p,q;
p = this.head;
this.head = null;
while(p != null){
q=p;
p=p.next;
q.next = this.head;
this.head = q;
}
}
- 两个链表的合并