简介
LinkedList 特点
双向链表实现
元素时有序的,输出顺序与输入顺序一致
允许元素为 null
要找到某个结点,必须从头开始遍历。(查询慢,增删快)
和 ArrayList 一样,不是同步容器
基本函数
函数应用
遍历List集合
(1)使用集合迭代器
(2)混合使用size()和get()
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public class BianliList {
public static void main(String[] args){
//创建集合对象
List l= new ArrayList();
//给集合添加元素
l.add("just");
l.add("a");
l.add("sec");
//遍历集合之使用迭代器
Iterator it= l.iterator();
while(it.hasNext()){
//System.out.print(it.next()+" ");//just a sec
String s= (String)it.next();
System.out.print(s+" "); //just a sec
}
//遍历集合之使用List的size()方法和get()方法
for(int index=0; index< l.size(); index++){
System.out.print(l.get(index)+" ");//just a sec
}
}
}
增删改查
- 添加:
public void add(int index, E element):指定位置添加指定的元素 public
boolean addAll(int index, Collection c):指定位置添加指定的集合 - 删除:
public E remove(int index):移除此列表指定位置的元素
boolean remove(Object o) :移除指定元素在此列表中的第一个出现(如果存在) - 获取:
E get(int index):返回列表中指定位置的元素
int indexOf(Object o):返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
int lastIndexOf(Object o):返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
List subList(int fromIndex, int toIndex) :返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 - 修改:
E set(int index, E element): 用指定元素替换列表中指定位置的元素
常见问题
【基础】链表的基础练习
输入
输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数。这一行整数是用来初始化列表的,并且输入的顺序与列表中的顺序相反,也就是说如果列表中是1、2、3那么输入的顺序是3、2、1。
第二行有一个整数m,代表下面还有m行。每行有一个字符串,字符串是“get”,“insert”,“delete”,“show”中的一种。如果是“get”或者“delete”,则其后跟着一个整数a,代表获得或者删除第a个元素;如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e;“show”之后没有整数。
输出
如果获取成功,则输出该元素;如果删除成功则输出“delete OK”;如果获取失败或者删除失败,则输出“get fail”以及“delete fail”。如果插入成功则输出“insert OK”,否则输出“insert fail”。如果是“show”则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”。注:所有的双引号均不输出。
示例
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
LinkedList list = new LinkedList();
LinkedList newList = new LinkedList();
for (int i = 0; i < n; i++){
list.add(scanner.nextInt());
}
for (int i = list.size()-1; i >= 0; i--){
newList.add(list.get(i));
//System.out.println(list.get(i));
}
int m = scanner.nextInt();
scanner.nextLine();
//System.out.println("m是" + m);
for(int i = 0; i<m; i++){
String opt;
opt = scanner.next();
if(opt.equals("show")){
int size = newList.size();
if (size == 0){
System.out.println("Link list is empty");
}
for (int j = 0; j<size; j++){
System.out.println(newList.get(j));
}
}else if(opt.equals("get")){
//System.out.println("opt是" + opt);
int num = scanner.nextInt();
if ((num-1) > newList.size()){
System.out.println("get fail");
}else {
System.out.println(newList.get(num - 1));
}
}else if(opt.equals("delete")){
//System.out.println("opt是" + opt);
int num = scanner.nextInt();
if ((num-1) > newList.size()){
System.out.println("delete fail");
}else {
newList.remove(num - 1);
System.out.println("delete OK");
}
}else if(opt.equals("insert")){
//System.out.println("opt是" + opt);
int a = scanner.nextInt();
int b = scanner.nextInt();
if ((a-1) > newList.size()){
System.out.println("insert fail");
}else {
newList.add(a - 1, b);
System.out.println("insert OK");
}
}else {
//System.out.println("error");
}
}
}
}
约瑟夫环问题
有n个人围成一圈,顺序从1开始排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。要求用循环链表实现。
输入:
10
输出:
4
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
LinkedList loop = new LinkedList();
int n = scanner.nextInt();
for(int i = 1; i <= n; i++){
loop.add(i);
}
int count = 1;
while(loop.size()>1){
for (int i = 0; i < loop.size(); i++){
if (count == 3){
count = 1;
loop.remove(i);
i--;
continue;
}
count++;
}
}
for(int i= 0;i<loop.size();i++){
System.out.println(loop.get(i));
}
}
}
1、查找倒数第K个结点;
2、链表反转;
3、逆序打印链表;
4、判断链表是否有环;
5、寻找中间结点。
public class MyLinkList {
static Node headNode=null;
public static void main(String[] args) {
MyLinkList list=new MyLinkList();
list.addNode(3);
list.addNode(4);
list.addNode(5);
list.addNode(2);
list.addNode(1);
//System.out.println(list.findCenterData(headNode));
System.out.println(list.isLoop(headNode));
//list.printByLast(headNode);
//list.reverseNode(headNode);
//list.printNode();
//System.out.println(list.findLastK(4));
}
//判断是否有环
public boolean isLoop(Node head)
{
Node fastNode=head;
Node slowNode=head;
if(fastNode==null)
return false;
while(fastNode!=null&&fastNode.next!=null)
{
fastNode=fastNode.next.next;
slowNode=slowNode.next;
if(fastNode.data==slowNode.data)
return true;
}
return !(fastNode==null||fastNode.next==null);
}
//寻找中间结点
public int findCenterData(Node head)
{
Node pNode=head;
Node qNode=head;
while(pNode!=null&&pNode.next!=null&&pNode.next.next!=null)
{
pNode=pNode.next.next;
qNode=qNode.next;
}
return qNode.data;
}
//递归逆序打印
public void printByLast(Node head)
{
Node pNode=head;
if(pNode!=null)
{
//pNode=pNode.next;
printByLast(pNode.next);
System.out.println(pNode.data);
}
}
//链表反转
public void reverseNode(Node head)
{
Node rNode=head;
Node pNode=head;
Node pPrevNode=null;
while(pNode!=null)
{
Node pNextNode=pNode.next;
if(pNextNode==null)
rNode=pNode;
pNode.next=pPrevNode;
pPrevNode=pNode;
pNode=pNextNode;
}
this.headNode=rNode;
}
//寻找倒数第K个结点
public int findLastK(int k)
{
int i=0;
Node p=headNode;
Node q=p;
while(q.next!=null)
{
i++;
if(i>=k)
{
p=p.next;
}
q=q.next;
}
return p.data;
}
//添加结点
public void addNode(int data)
{
Node newNode=new Node(data);
if(headNode==null)
{
headNode=newNode;
return;
}
Node tempNode=headNode;
while(tempNode.next!=null)
{
tempNode=tempNode.next;
}
tempNode.next=newNode;
}
// 打印结点
public void printNode()
{
Node temp=headNode;
while(temp!=null)
{
System.out.println(temp.data);
temp=temp.next;
}
}
}
//定义结点
class Node
{
Node next;
int data;
public Node(int data)
{
this.data=data;
}
}