链结点
链表是由一个个的链结点链接而成的,一个链结点由数据域(存放数据的部分)data和引用域(下一个结点的引用)next,下图显示了这一关系:
下面是一个链结点定义的一部分:
public class LinkNode {
private int idata;//数据域,这里的数据域只存放一个数,如果有很多的数据我们可以将数据封装一下
private LinkNode next;//引用域,这里仅仅表示引用,而不是实例化的对象
}
单链表
单链表是链表中最简单的一种,我们现在来实现一个单链表,它现在的操作包括:- 在链表头插入一个新的结点;
- 在链表头部删除一个结点;
- 遍历链表并打印。
这些操作都十分简单,这也是后续知识的基础。
LinkNode类完整代码:
public class LinkNode {
private int idata;//数据域
private LinkNode next;//引用域
public int getIdata() {
return idata;
}
public void setIdata(int idata) {
this.idata = idata;
}
public LinkNode getNext() {
return next;
}
public void setNext(LinkNode next) {
this.next = next;
}
//打印链结点数据域内容
public void displayNode(){
System.out.print(idata+"-->");
}
}
SingleLinkList类部分代码:
public class SingleLinkList {
//头结点,不存放数据,从头结点出发通过每个结点的next可以遍历整个链表
private LinkNode head;
public SingleLinkList(){
head = null;//其实这是可以省略的,默认会初始化为null
}
public boolean isEmpty(){
return head == null;
}
public LinkNode getHead() {
return head;
}
public void setHead(LinkNode head) {
this.head = head;
}
}
insertHead()方法
从头结点插入一个新的链结点。 插入操作流程:插入的顺序一定不能反了,否则会造成断链,插入失败。
public void insertHead(LinkNode newNode){
newNode.setNext(head);//图示第一步
head = newNode;//图示第二步
}
deleteHead()方法
从头部删除结点。 删除操作流程:public LinkNode deleteHead(){
if(isEmpty()){
System.out.println("链表为空");
return null;
}
LinkNode oldNode = head;//存储要删除的结点
head = head.getNext();
return oldNode;//返回删除的结点
}
displayList()方法
为了显示整个链表我们必须从头结点开始根据每一个链接点的next一个个遍历结点直至next为null为止。public void displayList(){
System.out.println("head --> end");
LinkNode temp = head;//获得第一个结点
while(temp!=null){
temp.displayNode();
temp = temp.getNext();//下一个结点
}
System.out.println();
}
测试这三个功能:
public class SingleLinkListTest {
public static void main(String[] args) {
LinkNode node1 = new LinkNode(10);
LinkNode node2 = new LinkNode(15);
LinkNode node3 = new LinkNode(12);
LinkNode node4 = new LinkNode(5);
LinkNode node5 = new LinkNode(4);
LinkNode node6 = new LinkNode(7);
LinkNode node7 = new LinkNode(2);
LinkNode node8 = new LinkNode(9);
SingleLinkList list = new SingleLinkList();
list.insertHead(node1);
list.insertHead(node2);
list.insertHead(node3);
list.insertHead(node4);
list.insertHead(node5);
list.insertHead(node6);
list.insertHead(node7);
list.insertHead(node8);
list.displayList();
System.out.println("删除了:"+list.deleteHead().getIdata());
System.out.println("删除了:"+list.deleteHead().getIdata());
System.out.println("删除了:"+list.deleteHead().getIdata());
list.displayList();
}
}
根据值或位置查找结点
查找的方法和displayList()方法很像,要一个个的遍历结点判断值或者位置是否符合要求。1. 根据值查找结点
public boolean findByval(int key){
LinkNode current = head;
while(current!=null){
if(current.getIdata()==key){
return true;
}
current= current.getNext();
}
return false;
}
2. 根据位置查找结点
public LinkNode findBypos(int pos){
int n=1;//记录遍历到第几个结点了
LinkNode current= head;
while(current!=null){
if(n == pos){
return current;
}
current= current.getNext();
n++;
}
return null;
}
根据值或位置删除结点
删除操作和前面的查找操作很类似,只是我们要删除某一个位置上的结点时我们必须有这一位置结点的前面一个结点。因为单链表是单向的我们无法通过当前结点直接得到前面一个结点。1. 根据值删除结点
//删除链表中所有值为key的结点
public void deleteByval(int key){
LinkNode previous = head;//存储前一个结点
LinkNode current = head;
while(current!=null){
if(current.getIdata() == key){
if(current == head){
head = head.getNext();//特殊情况,第一个结点就是我们要删除的那么head后移一下
}
previous.setNext(current.getNext());//普通情况
}
previous = current;
current = current.getNext();
}
}
2. 根据位置删除结点
//删除指定位置的结点
public void deleteBypos(int pos){
int n=1;
LinkNode previous = head;
LinkNode current = head;
while(current!=null){
if(n == pos){
if(pos==1){
head = head.getNext();
return;
}
previous.setNext(current.getNext());
}
previous = current;
current = current.getNext();
n++;
}
}
在指定位置后插入结点
有了前面的几个方法我们会很简单的实现这一功能。public void insertBypos(int pos,LinkNode newNode){
if(pos==0){//pos为0说明在头部插入结点,直接使用已经实现好的insert()方法
insertHead(newNode);
return;
}
LinkNode current = findBypos(pos);//根据位置找到该结点
if(current != null){//不为null说明查找成功
newNode.setNext(current.getNext());
current.setNext(newNode);
}
}