文章首发地址:知乎专栏 https://zhuanlan.zhihu.com/p/36309417
1 链表的简单介绍
链表(Linked List)是一种链式存取的数据结构,链表中的数据是以结点来表示的。具体表示结构如下:
data域--存放结点值的数据域
next域--存放结点的直接后继的地址(位置)的指针域
链表主要有三种:
单向链表(Singly Linked List)
双向链表(Doubly Linked List)
循环链表(Circular Linked List)
本文主要介绍下单向链表的增、删、改、查等基本操作,使用的语言为Java。
单向链表
2 单向链表的基本操作
2.1 创建结点类
//创建一个结点类,并用get,set方法获取其数据。
public class Node {
private int data; //数据域
private Node next; //指针域
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
//显示该结点的数据
public void display() {
System.out.print( data + " ");
}
}
2.2 创建链表类
public class SinglyLinkedList {
private Node head;//表头
private int length = 0;//获取链表的长度(结点的个数)
public SinglyLinkedList() {
this.head = null;
}
//在链表头部添加结点
public void addHead(int data) {
Node newNode = new Node(data);
if(head == null){
head = newNode;
}
else{
newNode.setNext(head);
head = newNode;
}
length++;//结点个数加1
}
//在链表头部删除结点
public Node deleteHead() {
if(head == null){
return head;
}
Node curNode = head;
head = curNode.getNext();
length--;//结点个数减1
return curNode;
}
//在链表尾部添加结点
public void addTail(int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
} else {
Node pre = head;
int count = 1;
while (count < length) {
pre = pre.getNext();
count++;
}
Node curNode = pre.getNext();//最后结点的next指针,即指向null
newNode.setNext(curNode);//新结点的next指针指向最后结点的next指针
pre.setNext(newNode);//最后结点的next指针指向新结点
}
length++;//结点个数加1
}
//在链表尾部删除结点
public Node deleteTail() {
if(head == null){
return head;
}
Node preNode = head;
int count = 1;
while(count < length-1) {
preNode = preNode.getNext();
count++;
}
Node curNode = preNode.getNext();//指向最后一个结点
preNode.setNext(curNode.getNext());//指向最后一个结点next指针值null
length--;
return null;
}
//遍历链表,也可用此方法添加计数器获取链表长度
public void printAllNode() {
Node cur = head;
while (cur != null) {
cur.display();//显示此结点的数据
cur = cur.getNext();
}
System.out.println();
}
//获取链表的长度
public int listLength() {
return length;
}
//在指定位置插入结点
public void insertList(int data, int index) {
Node newNode = new Node(data);
if(head == null){
head = newNode;//链表为空,插入
}
if(index > length+1 || index < 1) {
System.out.println("结点插入的位置不存在,可插入的位置为1到"+(length+1))
}
if(index == 1) {
newNode.setNext(head);
head = newNode;//在链表开头插入
}
else{ //在链表中间或尾部插入
Node preNode = head;
int count = 1;
while(counter < index-1) {
preNode = preNode.getNext();
count++;
}
Node curNode = preNode.getNext();
newNode.setNext(curNode);
preNode.setNext(newNode);
}
length++;
}
//在指定位置删除结点
public Node deleteList(int index) {
if(index > length || index < 1) {
System.out.println("结点删除的位置不存在,可删除的位置为1到"+length);
}
if(index == 1) { //删除表头结点
Node curNode = head;
head = curNode.getNext();
length--;
return curNode;
}
else{ //删除链表中间或尾部结点
Node preNode = head;
int count = 1;
while(counter < index-1) {
preNode = preNode.getNext();
count++;
}
Node curNode = preNode.getNext();
preNode.setNext(curNode.getNext());
length--;
return curNode;
}
}
//查找数据是否存在
public boolean containData(int data) {
if(head == null){
System.out.println("空表");
return false;
}
Node curNode = head;
while(curNode.getData()!= data){
if(curNode.getNext() == null) {
System.out.println("结点数据不存在");
return false;
}
curNode =curNode.getNext();
}
System.out.println("结点数据存在");
return true;
}
//获取指定位置的数据
public void getIndexData(int index) {
if(head == null){
System.out.println("空表");
}
if(index > length || index < 1) {
System.out.println("结点位置不存在,可获取的位置为1到"+length);
}
Node curNode = head;
int count =1;
while(count != index) {
curNode =curNode.getNext();
count++;
}
curNode.display();//显示该位置的结点数据
System.out.println();
}
//修改指定位置的结点数据,与获取指定位置的数据的方法基本一致。
public void updateIndexData(int index, int data) {
if(head == null){
System.out.println("空表");
}
if(index > length || index < 1) {
System.out.println("结点位置不存在,可更新的位置为1到"+length);
}
Node curNode = head;
int count =1; //也可以用for循环方式求取
while(count != index) {
curNode =curNode.getNext();
count++;
}
curNode.setData(data);//将获取的指定位置的数据修改为指定的数据
}
3 建立测试类
测试类建立如下,运行结果这里不再赘述。
public class LinkedListTest {
public static void main(String[] args) {
SinglyLinkedList list = new SinglyLinkedList();
list.addHead(3);
list.addHead(2);
list.addHead(1);
list.addTail(4);
list.addTail(5);
list.printAllNode();
list.insertList(8,2);
list.printAllNode();
list.deleteHead();
list.printAllNode();
list.deleteTail();
list.printAllNode();
list.deleteList(1);
list.printAllNode();
list.containData(2);
list.getIndexData(4);
list.updateIndexData(4,100);
list.printAllNode();
}
}
4 参考资料
[1] 数据结构与算法经典问题解析
[2] 用java简单的实现单链表的基本操作 - CSDN博客