链表
链表(Linked list)是一种常见的线性数据结构。单向链表中每个结点都有一个next指针指向下一个结点,双向链表则多一个指向上一个结点的指针。搜索链表和查找第n个数据的时间复杂度都是O(n)。链表的优势在于在任意位置删除和插入数据时效率高(不用改变其他节点位置)
一. 单链表的定义以及一些基本操作实现(java)
/*
* 定义一个结点类
*/
public class Node {
Node next; //指向下一结点的指针
int data; //该节点存储数据
public Node(int data){
this.data = data;
}
//显示此结点
public void show(){
System.out.print(data + " ");
}
}
/*
* 定义一个链表主类,并且定义各种对链表操作的方法
*/
public class List {
public Node head; //定义一个头结点
public Node tail; //定义一个尾指针
//定义一个空链表
public List(){
head = null;
tail = head;
}
//插入结点(2种)
public void addToList(int data){ //1.在尾部直接插入
Node node = new Node(data);
if(head == null){
head = node;
}else{
tail.next = node;
}
tail = node;
}
public void addToList(int index, int data){ //2.在任意位置插入
Node node = head;
int i = 0;
while(node!=null && i<index-2){
node = node.next;
i++;
}
Node insert = new Node(data);
insert.next = node.next;
node.next = insert;
}
//删除一个结点(2种)
public void deleteByIndex(int index){ //1.根据位置删除
Node node = head;
int i = 0;
while(node!=null && i<index-2){
node = node.next;
i++;
}
node.next = node.next.next;
}
public void deleteByData(int data){ //2.根据数据删除(只操作第一个)
Node current = head;
Node previous = head; //记住上一个节点
int i = 0;
while (current.data != data){
if(current.next == null){
i = 1;
break;
}
previous = current;
current = current.next;
}
if(i==0){
if(current == head) {
head = head.next;
}else{
previous.next = current.next;
}
}
}
//改变指定位置的结点数值
public void change(int index, int data){
Node node = head;
int i = 0;
while(node!=null && i<index-2){
node = node.next;
i++;
}
node.next.data = data;
}
//查找结点信息(3种)
public void showAllNodes(){ //1.显示所有结点信息
Node node = head; //还可以用递归形式遍历
while(node!=null){
node.show();
node = node.next;
}
System.out.println();
}
public Node findByIndex(int index){ //2.根据位置查找
Node node = head;
int i = 0;
while(node!=null && i<index-1){
node = node.next;
i++;
}
return node;
}
public Node findByData(int data){ //3.根据数据查找(只操作第一个)
Node current = head;
while(current.data != data){
if(current.next == null)
return null;
else
current = current.next;
}
return current;
}
}
二. 面试中经常出现的链表相关问题(用java实现)
(没有实现的,后续一一补充)
- 1.求单链表中结点的个数
public int getLength(Node head){
if(head == null){
return 0;
} //注意链表为空时的情况
else{
Node node = head;
int length = 0;
while(node != null){
length++;
node = node.next;
}
return length;
}
}
2.将单链表反转
3.查找单链表中的倒数第K个结点(k > 0)
4.查找单链表的中间结点
5.从尾到头打印单链表
6.已知两个单链表各自有序,把它们合并成一个链表依然有序
7.判断一个单链表中是否有环
8.判断两个单链表是否相交
9.求两个单链表相交的第一个节点
10.已知一个单链表中存在环,求进入环中的第一个节点
11.给出一单链表头指针和一节点指针,O(1)时间复杂度删除该节点