Java 链表操作
- 格式:docx
- 大小:27.64 KB
- 文档页数:5
Java散列表以拉链法解决冲突问题(以电话簿为例)原理哈希表的结构哈希表⼜被称为数组链表。
当插⼊删除操作和取值操作都较频繁时,我们可以采⽤哈希表来作为集合的数据结构。
定义:哈希表(Hash table,也叫散列表),是根据关键码值(Key value)⽽直接进⾏访问的数据结构。
也就是说,它通过把关键码值映射到表中⼀个位置来访问记录,以加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做散列表。
⼤致结构如下但是本例题未采⽤Java⾃带的hash集合特点:1.第⼀列是⼀个数组。
因此我们在查找每⼀个链表头结点位置所耗费的时间复杂度都是常数1;2.每⼀⾏都是⼀个链表。
理论上,这个链表可以⽆限扩⼤。
实际上当然是不⾏的,我们可以设想两种极端情况。
⼀种是链表的长度远远⼤于头结点数组的长度,那么这时这个哈希表其实就相当于⼀个链表,它取值操作的时间复杂度还是接近n。
另⼀种情况就是链表的长度远远⼩于头结点数组的长度,那么这时这个哈希表其实就相当于⼀个数组,它插⼊和删除操作的时间复杂度还是接近n。
为了避免这两种极端情况的出现,我们引⼊了⼀个控制变量peakValue(当前哈希表的数据个数/数组长度)。
如果这个值超过了某⼀界限,我们就对当前的哈希表进⾏重构。
3.每⼀次存放和取出数据,都是先找到对应的⾏号(即头结点的位置),然后再去遍历该⾏链表中的各个数据。
哈希表的构建思路基本思路:⾸先我们需要开辟⼀个连续的数组来储存每个头结点,这个数组的⼤⼩是固定的。
每当我们从⽂件中读取出⼀个电话簿,⾸先要将其封装成⼀个节点。
然后根据number计算出相应的code,这个code会定位到唯⼀的⼀个链表头。
最后再把数据放到这个链表⾥⾯。
源代码import java.io.File;import java.io.FileNotFoundException;import java.util.Scanner;public class worktest {class Listnode {String name;String number;Object key;Listnode next;Listnode() {};Listnode(String name, String number) { = name;this.number = number;}Listnode(String name, String number, Listnode next) { = name;this.number = number;this.next = next;}}public void read_file(Listnode []node){File file = new File("d://电话号码.txt");if (!file.exists()){System.out.println("该⽂件不存在");System.exit(0);}try {Scanner scanner = new Scanner(file);while(scanner.hasNext()){String name = scanner.next();String number = scanner.next();Listnode listnode = new Listnode(name,number);listnode.next = null;int i = (number.charAt(10)-'0')%10;//除10取余// System.out.println(i);if(node[i] == null){//简单拉链法存数据node[i] = listnode;}else{listnode.next = node[i].next;node[i].next = listnode;}}} catch (FileNotFoundException e) {e.printStackTrace();}}public void show(Listnode []node){//输出电话簿Listnode listnode = new Listnode();for (int i = 0; i < 10; i++) {listnode = node[i];while (listnode!=null){System.out.println(+" "+listnode.number);listnode = listnode.next;}}}public void search1(Listnode []node, String name){//根据姓名查找 Listnode listnode = new Listnode();for (int i = 0; i < 10; i++) {listnode = node[i];while (listnode != null){if (.equals(name)){System.out.println(+" "+listnode.number); }listnode = listnode.next;}}}public void search2(Listnode []node, String number){//根据电话查找 Listnode listnode = new Listnode();for (int i = 0; i < 10; i++) {listnode = node[i];while (listnode != null){if (listnode.number.equals(number)){System.out.println(+" "+listnode.number); }listnode = listnode.next;}}}public static void main(String[] args) {Scanner in = new Scanner(System.in);worktest test = new worktest();Listnode []node = new Listnode[10];//key%10test.read_file(node);// test.show(node);while(true){System.out.println("请选择查找⽅式:1.按姓名查找,2.按电话查找,(输出其他退出)");int choice = in.nextInt();if (choice == 1){String name = in.next();long startTime = System.currentTimeMillis();//计算查找所消耗的时间test.search1(node,name);long endTime = System.currentTimeMillis();System.out.println("本次查找消耗时间为"+(endTime-startTime)+"微秒");}else if(choice == 2){String number = in.next();long startTime = System.currentTimeMillis();test.search2(node,number);long endTime = System.currentTimeMillis();System.out.println("本次查找消耗时间为"+(endTime-startTime)+"微秒");}elsebreak;}}}⽂件截图总结反思1.把⼀个String字符串转化为int型整数有两种意思。
linkedlist用法Linkedlist用法Linkedlist是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和一个指向下一个节点的指针。
Linkedlist可以用于实现栈、队列、图等数据结构,也可以作为一种独立的数据结构使用。
1. 创建Linkedlist创建一个空的Linkedlist非常简单,只需要定义一个头指针即可。
头指针通常被定义为一个结构体类型的变量,其中包含指向第一个节点和最后一个节点的指针。
2. 插入节点在Linkedlist中插入新的节点有两种方式:在链表头部插入或在链表尾部插入。
对于单向链表来说,在链表中间插入新的节点比较困难。
2.1 在链表头部插入新的节点在链表头部插入新的节点是最简单、最快速的方式。
只需要将新的节点作为第一个节点,并将原来第一个节点作为新节点后面的那个节点即可。
2.2 在链表尾部插入新的节点在链表尾部插入新的节点需要遍历整个链表找到最后一个节点,并将其指向新的节点。
这个过程比较耗时,但是可以保证新加进来的元素总是排在最后面。
3. 删除节点删除Linkedlist中某个特定位置上的元素也有两种方式:删除头部元素或删除尾部元素。
对于单向链表来说,在链表中间删除节点比较困难。
3.1 删除头部元素删除头部元素非常简单,只需要将头指针指向第二个节点即可。
3.2 删除尾部元素删除尾部元素需要遍历整个链表找到倒数第二个节点,并将其指向NULL。
这个过程比较耗时,但是可以保证被删除的元素总是排在最后面。
4. 遍历Linkedlist遍历Linkedlist可以使用循环或递归的方式实现。
循环的方式比较简单,只需要从头指针开始一直遍历到最后一个节点即可。
递归的方式比较复杂,但是可以更加灵活地处理数据。
5. 反转Linkedlist反转Linkedlist也有两种方式:迭代和递归。
迭代的方式需要用三个指针分别表示当前节点、前一个节点和后一个节点,然后依次将当前节点指向前一个节点,并更新三个指针的位置。
Java LinkedList 类提供了许多方法,用于操作链表。
以下是一些常用的LinkedList 方法:1. add(E e):在链表末尾添加元素e。
2. add(int index, E element):在指定位置index 插入元素element。
3. addFirst(E e):在链表头部添加元素e。
4. addLast(E e):在链表尾部添加元素e。
5. clear():移除链表中的所有元素。
6. contains(Object o):判断链表中是否包含元素o。
7. containsAll(Collection<?> c):判断链表中是否包含集合c 中的所有元素。
8. get(int index):获取链表中指定位置index 的元素。
9. getFirst():获取链表头部的元素。
10. getLast():获取链表尾部的元素。
11. remove(Object o):移除链表中第一个出现的指定元素o。
12. remove(int index):移除链表中指定位置index 的元素。
13. removeFirst():移除链表头部的元素。
14. removeLast():移除链表尾部的元素。
15. size():返回链表中元素的个数。
16. isEmpty():判断链表是否为空。
17. isSingleton():判断链表是否只有一个元素。
18. poll():移除并返回链表头部的元素,如果链表为空则返回null。
19. pop():移除并返回链表尾部的元素,如果链表为空则抛出NoSuchElementException 异常。
20. peek():返回链表头部的元素,但不移除,如果链表为空则返回null。
21. push(E e):将元素e 添加到链表头部。
22. offer(E e):将元素e 添加到链表尾部,如果成功则返回true,否则返回false。
23. removeFirstOccurrence(Object o):移除链表中第一个出现的指定元素o。
list在java中的用法在Java中,List是一个接口,它代表着有序的集合。
它允许存储重复的元素,并且能够根据元素的索引来访问和操作集合中的元素。
常用的实现类有ArrayList和LinkedList。
以下是List在Java中的一些主要用法:1. 创建List对象:List<T> list = new ArrayList<T>(); // 创建一个ArrayList对象 List<T> list = new LinkedList<T>(); // 创建一个LinkedList对象2. 添加元素到List中:list.add(element); // 添加元素到末尾list.add(index, element); // 在指定位置插入元素3. 获取List中的元素:T element = list.get(index); // 获取指定位置的元素4. 更新List中的元素:list.set(index, element); // 更新指定位置的元素5. 删除List中的元素:list.remove(index); // 删除指定位置的元素list.remove(element); // 删除指定元素6. 判断List是否包含指定元素:boolean contains = list.contains(element);7. 获取List的大小:int size = list.size();8. 遍历List中的元素:for (T element : list) {// 处理每个元素}9. 将List转换为数组:T[] array = list.toArray(new T[list.size()]);10. 使用迭代器遍历List:Iterator<T> iterator = list.iterator();while (iterator.hasNext()) {T element = iterator.next();// 处理每个元素}这些是List在Java中的主要用法,通过它们可以方便地对集合中的元素进行增删改查操作。
双向链表逆序双向链表的逆序操作可以通过修改节点之间的引用关系来实现。
具体步骤如下:1. 定义三个指针:pre表示当前节点的前一个节点,cur表示当前节点,next表示当前节点的后一个节点;2. 遍历整个链表,初始时将pre设置为null,cur设置为链表的头节点;3. 在遍历过程中,先将next指向cur的后一个节点;4. 将cur的next指向pre,将cur的prev指向next。
5. 更新pre和cur,将cur指向next,pre指向cur;6. 重复步骤3~5,直到遍历到链表的最后一个节点。
7. 将最后一个节点的prev指向null,表示链表逆序完成。
以下是Java代码示例:```public class DoublyLinkedList {Node head;class Node {int data;Node prev;Node next;Node(int d) {data = d;prev = null;next = null;}}public void reverse() {Node temp = null;Node current = head;while (current != null) {temp = current.prev;current.prev = current.next;current.next = temp;current = current.prev;}if (temp != null) {head = temp.prev;}}}```注意:逆序之后,原来的头结点会变成尾结点,原来的尾结点会变成头结点。
单链表的操作方法一:package ch02;(1)建立结点类Node.javapublic class Node {public Object data;//存放结点数据值public Node next;//存放后继结点//无参构造函数public Node(){ this(null,null);}//只有结点值的构造函数public Node(Object data){ this(data,null);}//带有节点值和后继结点的构造函数public Node(Object data,Node next){ this.data=data;this.next=next;}}(2)建立链表及操作LinkList.javapackage ch02;import java.util.Scanner;public class LinkList implements IList{public Node head;//单链表的头指针//构造函数初始化头结点public LinkList(){head=new Node();}//构造函数构造长度为n的单链表public LinkList(int n,boolean Order) throws Exception{ this();if(Order)create1(n); //头插法顺序建立单链表elsecreate2(n); //尾插法逆序建立单链表}//头插法顺序建立单链表public void create1(int n) throws Exception{Scanner sc=new Scanner(System.in);System.out.println("请输入结点的数据(头插法):”);for(int i=0;i<n;i++){insert(0,sc.next());}}//尾插法逆序建立单链表public void create2(int n) throws Exception{Scanner sc=new Scanner(System.in);System. out.println("请输入结点的数据(尾插法):");for(int i=0;i<n;i++){insert(length(),sc.next());}}//将链表置空public void clear(){head.data=null;head.next=null;}//判断链表是否为空public boolean isEmpty(){return head.next==null;}//返回链表长度public int length(){Node p=head.next;int length=0;while(p!=null){p=p.next;length++;//返回P不空长度length加1}return length;}//读取并返回第i个位置的数据元素public Object get(int i) throws Exception {Node p=head.next;int j;//从首结点开始向后查找,直到9指向第i个结点或者p为nullfor(j=0;j<i&&p!=null;j++){ p=p.next;}if(j>i||p==null)//i不合法时抛出异常throw new Exception("第"+i+”个数据元素不存在”);return p.data;}//插入乂作为第i个元素public void insert(int i, Object x) throws Exception{ Node p=head;int j=-1;//寻找第i个结点的前驱i-1while(p!=null&&j<i-1){p=p.next;j++;}if(j>i-l||p==null)//i不合法时抛出异常throw new Exception("插入位置不合法”);Node s=new Node(x);s.next=p.next;p.next=s;}//删除第i个元素public void remove(int i) throws Exception{ Node p=head;int j=-1;while(p!=null&&j<i-1){//寻找第i-1 个节点p=p.next;j++;}if(j>i-1||p.next==null)throw new Exception("删除位置不合法”);p.next=p.next.next;}//返回元素x首次出现的位序号public int indexOf(Object x) {Node p=head.next;int j=0;while(p!=null&&!p.data.equals(x)){p=p.next;j++;if(p!=null)return j;elsereturn -1;}public void display(){Node p=head.next;while(p!=null){if(p.next==null)System.out.print(p.data);elseSystem.out.print(p.data+"f );p=p.next;}}}(3)建立测试类Test.javappublic class test {public static void main(String[] args) throws Exception { // TODO Auto-generated method stubScanner sc=new Scanner(System.in);boolean or;int xz,xx;System.out.println("请选择插入的方法:0、头插法,1、尾插法");xz=sc.nextInt();if(xz!=0)or=true;elseor=false;System. out.println("请插入的结点的个数:”);xx=sc.nextInt();LinkList L=new LinkList(xx,or);System.out.println("建立的链表为:");L.display();System.out.println();System.out.println("链表的长度:"+L.length());System. out.println(”请输入查找的结点的数据:”);Object x=sc.next();int position=L.indexOf(x);System.out.println("结点的数据为:"+x+"的位置为:"+position); System. out.println("请输入删除的结点的位置:”);int sr=sc.nextInt();L.remove(sr);L.display();System.out.println();System.out.println("链表的长度:"+L.length()); }品P rob I em & J a vs d oc / Declaration Q Error Log 里Con sole-M、、■=:termin8ted> test [3] [Java Application] C U &ert\Ad im i n i st rat o r\Ap p Data\L o cs I请选择插入.的方法:0、头插法,lv星插法请插入的特点的个数:请愉入结点的颓据(尾插法):A B C E D F建立的旌表为;A+B T C+E T D+F链表的长度:6请输入查找的结点的数据:结点的数据为:E的位置为:3请输入删除的结点的位置,R+B T E+DW道表的长度:S方法二(引入get和set方法)Package sy;import java.util.Scanner;//单链表的结点类public class Node {private Object data; //存放结点值private Node next; //后继结点的引用public Node() { //无参数时的构造函数this(null, null);}public Node(Object data) { // 构造值为data 的结点this(data, null);}public Node(Object data, Node next) {//构造值为data 和next 的结点构造函数this.data = data;this.next = next;}public Object getData() { return data;}public void setData(Object data) {this.data = data;}public Node getNext() { return next;public void setNext(Node next) { this.next = next;}}//实现链表的基本操作类public class LinkList {Node head=new Node();//生成一个带头结点的空链表//根据输入的一系列整数,以0标志结束,用头插法建立单链表public void creat() throws Exception {Scanner sc = new Scanner(System.in); //构造用于输入的对象for (int x=sc.nextInt(); x!=0; x=sc.nextInt()) //输入若干个数据元素的值(以0结束) insert(0, x);//生成新结点,插入到表头}//返回带头结点的单链表中第i个结点的数据域的值。
java链式写法Java链式写法是一种编程风格,它允许在一个语句中使用多个方法调用,从而使代码更加简洁和易于阅读。
链式写法通常用于构建复杂的对象或执行一系列相关的操作。
下面是一个简单的例子,演示如何使用链式写法创建一个字符串:```String str = new StringBuilder().append("Hello").append(" ").append("World").toString();```在这个例子中,我们使用StringBuilder类创建一个字符串,并使用append()方法将“Hello”、“”和“World”添加到字符串中。
最后,我们使用toString()方法将StringBuilder对象转换为字符串。
注意,每个方法调用都返回一个对象本身,因此我们可以在同一行上调用多个方法。
这使得代码更加简洁和易于阅读。
链式写法还可以用于其他类和方法。
例如,我们可以使用链式写法设置JavaFX中的节点属性:```Button button = new Button().setText("Click me!").setPrefSize(100, 50).setOnAction(e -> System.out.println("Button clicked!"));```在这个例子中,我们使用链式写法设置按钮的文本、首选大小和单击事件处理程序。
这使得代码更加简洁和易于阅读。
总之,Java链式写法是一种简洁、易于阅读的编程风格,可以使代码更加优雅和易于维护。
图解Java数据结构之环形链表本篇⽂章介绍数据结构中的环形链表。
介绍环形链表,类似于单链表,也是⼀种链式存储结构,环形链表由单链表演化过来。
单链表的最后⼀个结点的链域指向NULL,⽽环形链表的建⽴,不要专门的头结点,让最后⼀个结点的链域指向链表结点。
简单点说链表⾸位相连,组成环状数据结构。
如下图结构:⽽在环形链表中,最为著名的即是约瑟夫环问题。
约瑟夫环问题问题介绍:设编号为1、2、3、... 、n的n个⼈围坐⼀圈,约定编号为k(1<=k<=n)的⼈从1开始报数,数到m的那个⼈出列,它的下⼀位⼜从1开始报数,数到m的那个⼈⼜出列。
依次类推,直到所有⼈出列为⽌,由此产⽣⼀个出队编号的序列。
我们可以举个例⼦来分析⼀下:假设⼀共有5个⼈,即n = 5;从第⼀个⼈开始报数,即k = 1;数到2的⼈出列,即m = 2。
⽰意图如下:出队列的顺序即为:2 -> 4 -> 1 -> 5 -> 3那么我们⾸先得构建出⼀个单向的环形链表。
实现分析:1. 先创建第⼀个节点,让first指向该节点,并形成环状2. 每创建⼀个新的节点就将该节点加⼊到已有的环形链表中分析完毕,我们⽤代码实现⼀下://创建⼀个环形的单向链表class CircleSingleLinkedList {// 创建⼀个first节点,当前没有编号private Boy first = null;// 添加节点,构建成⼀个环形链表System.out.println("数据错误");return;}// 定义辅助节点Boy curBoy = null;// 使⽤循环创建环形链表for (int i = 1; i <= nums; i++) {// 根据编号创建节点Boy boy = new Boy(i);// 如果是第⼀个节点if (i == 1) {first = boy;first.setNext(first);curBoy = first;// 让curBoy指向第⼀个节点,帮助构建链表} else {curBoy.setNext(boy);boy.setNext(first);// 使其指向第⼀个节点,形成环状curBoy = boy;// curBoy后移}}}// 遍历当前环形链表public void list() {// 判断链表是否空if (first == null) {System.out.println("链表为空");return;}// 定义辅助节点Boy curBoy = first;while (true) {System.out.println("节点编号:" + curBoy.getNo());if (curBoy.getNext() == first) {// 此时说明遍历完毕break;}curBoy = curBoy.getNext();// curBoy后移}}}//创建⼀个Boy类,表⽰⼀个节点class Boy {private int no;// 编号private Boy next;// 指向下⼀个节点public Boy(int no) {this.no = no;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public Boy getNext() {return next;}public void setNext(Boy next) {this.next = next;}}这样就实现了⼀个环形链表,接下来测试⼀下:public static void main(String[] args) {CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList(); circleSingleLinkedList.addBoy(5);circleSingleLinkedList.list();}运⾏结果:节点编号:1运⾏结果也是没有问题的,接下来便是⽣成出圈序列。
linkedlist的常用方法链表(LinkedList)是一种数据结构,具有非常独特的特性,它以节点为单位存储数据,每个节点都有一个指向下一个节点的指针,可以非常方便的进行数据的插入和删除操作。
在Java中,LinkedList是Java Collection Frameworks中比较常用的一种数据结构,下面就来介绍一下LinkedList的常用方法。
一、添加元素1. add(E e):在链表末尾添加元素e。
2. addFirst(E e):在链表头部添加元素e。
3. addLast(E e):与add(E e)一样,在链表末尾添加元素e。
4. add(int index, E e):在指定索引位置index处添加元素e。
二、获取元素1. get(int index):获取指定索引位置index处的元素。
2. getFirst():获取链表头部的元素。
3. getLast():获取链表末尾的元素。
三、删除元素1. remove():删除并返回链表首个元素。
2. removeFirst():删除并返回链表头部元素。
3. removeLast():删除并返回链表末尾元素。
4. remove(int index):删除指定索引位置index处的元素。
5. remove(Object o):删除链表中的元素o。
四、其他操作1. size():获取链表中元素个数。
2. clear():清空链表中所有元素。
3. contains(Object o):判断链表中是否包含元素o。
4. iterator():返回一个迭代器,可以迭代访问所有元素。
5. toArray():将链表转换为数组。
注:add()方法可以直接添加任意类型的元素,不受类型限制。
链表的特点是元素可以任意添加、删除,这种特点在实际程序开发中的应用广泛。
比如Java中的栈、队列、双向队列就是基于LinkedList实现的。
另外,链表与数组的区别在于索引访问速度,链表的访问速度比数组慢。
在Java中,ListNode通常用于表示链表中的一个节点。
链表是一种线性数据结构,其中每个元素(节点)都包含数据和指向下一个元素的引用。
以下是一个简单的ListNode类的实现示例:javapublic class ListNode {int val; // 节点值ListNode next; // 指向下一个节点的引用// 构造函数public ListNode(int val) {this.val = val;this.next = null;}}在这个示例中,ListNode类包含两个成员变量:val和next。
val变量用于存储节点的值,而next变量则是一个指向下一个节点的引用。
你可以使用ListNode类来创建和操作链表。
以下是一个简单的示例,展示如何创建一个包含几个节点的链表:java// 创建节点ListNode node1 = new ListNode(1);ListNode node2 = new ListNode(2);ListNode node3 = new ListNode(3);// 构建链表node1.next = node2; // node1指向node2node2.next = node3; // node2指向node3在这个示例中,我们创建了三个节点(node1、node2和node3),然后通过设置它们的next 引用构建了一个链表。
这个链表的顺序是:node1 -> node2 -> node3。
你还可以在链表上进行各种操作,如遍历、插入节点和删除节点等。
以下是一个简单的遍历链表的示例:java// 遍历链表ListNode current = node1; // 从头节点开始遍历while (current != null) {System.out.println(current.val); // 输出节点的值current = current.next; // 移动到下一个节点}这个示例从链表的头节点(node1)开始遍历,并逐个输出每个节点的值,直到遇到空节点(链表的末尾)。
java linkedlist的常用方法Java LinkedList 是Java集合框架中提供的一个双向链表实现类。
它提供了许多常用的方法,方便我们对链表进行操作和管理。
本文将介绍LinkedList的常用方法,包括添加元素、删除元素、获取元素、修改元素、查找元素等操作。
1. 添加元素LinkedList提供了多种方法来添加元素。
常用的方法有:- add(E e):在链表末尾添加一个元素。
- addFirst(E e):在链表头部插入一个元素。
- addLast(E e):在链表末尾插入一个元素。
- add(int index, E element):在指定位置插入一个元素。
2. 删除元素LinkedList也提供了多种方法来删除元素。
常用的方法有:- remove():删除并返回链表的第一个元素。
- removeFirst():删除并返回链表的第一个元素。
- removeLast():删除并返回链表的最后一个元素。
- remove(int index):删除指定位置的元素。
3. 获取元素LinkedList提供了多种方法来获取元素。
常用的方法有:- getFirst():返回链表的第一个元素。
- getLast():返回链表的最后一个元素。
- get(int index):返回指定位置的元素。
4. 修改元素LinkedList允许修改链表中的元素。
常用的方法有:- set(int index, E element):将指定位置的元素替换为新的元素。
5. 查找元素LinkedList提供了多种方法来查找元素。
常用的方法有:- contains(Object o):判断链表中是否包含指定的元素。
- indexOf(Object o):返回链表中第一次出现指定元素的索引。
- lastIndexOf(Object o):返回链表中最后一次出现指定元素的索引。
6. 遍历元素LinkedList可以使用迭代器或增强for循环来遍历元素。
链表的逆序
链表的逆序是指将链表中每个节点的指针方向从原来的下一个节点变
为指向前一个节点,并将原链表的头节点作为新链表的尾节点。
具体实现方法如下:
1. 定义三个指针:prev, cur, next。
分别代表当前节点的前驱节点、当前节点、当前节点的后继节点。
2. 初始化prev和cur指针,其中prev指向null或者哨兵节点,
cur指向头节点。
3. 遍历链表,将cur节点指向的下一个节点保存到next指针中,然
后将cur节点的next指针指向prev,即将链表方向反转。
4. 将prev指针移动到cur节点的位置,cur指针移动到next节点
的位置,即prev = cur,cur = next。
5. 直到遍历完整个链表,此时prev指针指向的是原链表的尾节点,
反转后的链表的头节点是cur指针指向的节点。
代码示例:
```java。
public ListNode reverseList(ListNode head) 。
if(head == null || head.next == null)。
return head;。
}。
ListNode prev = null;。
ListNode cur = head;。
while(cur != null)。
ListNode next = cur.next;。
cur.next = prev;。
prev = cur;。
cur = next;。
}。
return prev;。
}。
链表常用方法
1.增加节点:链表的特性就是可以动态增加节点,常用的方式是在链表末尾添加新节点或在指定节点后添加新节点。
2. 删除节点:删除节点时需要注意保持链表的连续性,一般有
两种方式,一种是将该节点的前一个节点直接指向该节点的下一个节点,另一种是将该节点的值设为 null 或者其他特殊值,将该节点标记为删除。
3. 遍历链表:使用循环语句对链表进行遍历,依次访问每个节
点即可。
4. 查找节点:查找链表中的某个节点时可以使用循环遍历或者
递归查找的方式,如果链表是有序的,则可以使用二分查找的方式。
5. 反转链表:将链表中节点的指针反转即可实现链表的反转,
可以使用迭代或者递归的方式实现。
6. 合并链表:将两个有序链表合并成一个有序链表,可以使用
迭代或者递归的方式实现。
7. 判断链表是否存在环:使用两个指针分别从链表头开始遍历,一个指针每次移动一个节点,另一个指针每次移动两个节点,如果存在环,则两个指针一定会相遇。
8. 找到环的起点:使用上一步中相遇的节点作为起点,再使用
两个指针分别从该节点和链表头开始遍历,相遇的节点即为环的起点。
9. 删除倒数第 n 个节点:使用快慢指针的方式找到倒数第 n
个节点,然后删除该节点即可。
10. 检测链表是否回文:使用快慢指针将链表分成两部分,将后半部分反转,然后比较两部分是否相等。
listnode用法java -回复listnode是一种在Java编程语言中常用的数据结构。
它是一种线性表,其中的每个元素都包含一个数据项和一个指向下一个元素的指针。
这种数据结构常用于实现栈、队列和链表等数据结构。
本文将详细介绍listnode 的用法及其在Java程序设计中的应用。
第一步:了解listnode的定义和基本操作在开始使用listnode之前,我们首先需要了解它的定义和基本操作。
在Java中,我们可以使用类来实现listnode。
一个典型的listnode类定义如下:class ListNode{int val;ListNode next;ListNode(int x) { val = x; }}在上述代码中,我们定义了一个名为ListNode的类,它包含一个整型数据项和一个指向下一个listnode的指针。
构造函数用于初始化数据项的值。
基本操作包括插入、删除和访问元素等。
我们可以在listnode类中定义这些操作的方法。
例如,插入一个新的元素到listnode中的方法可以定义如下:public void insert(int x){ListNode newNode = new ListNode(x);ListNode temp = this.next;this.next = newNode;newNode.next = temp;}在上述代码中,我们创建一个新的listnode,并将其插入到当前listnode 的后面。
需要注意的是,插入操作可能会改变listnode的长度以及指针的指向。
第二步:使用listnode实现栈和队列栈和队列是两种常用的数据结构,我们可以使用listnode来实现它们。
栈是一种后进先出(LIFO)的结构,而队列是一种先进先出(FIFO)的结构。
首先,让我们来实现一个栈的类。
我们可以使用listnode作为栈中的元素,并提供push和pop操作来向栈中插入和删除元素。
java的链式语法Java的链式语法是指一种通过使用点操作符(.)连接多个方法调用的编码风格。
这种风格使得代码更加简洁、易读,并且可以在一行代码中完成多个操作。
下面将详细介绍一些常见的链式语法的应用场景和示例。
1. 字符串操作:在Java中,字符串是不可变的,每次对字符串进行操作都会创建一个新的字符串对象。
使用链式语法可以在一行代码中完成多个字符串操作,提高效率并减少代码量。
例如,我们要将一个字符串转换为大写,并且去除首尾空格:String str = " hello world ";String result = str.trim().toUpperCase();System.out.println(result); // 输出:HELLO WORLD2. 集合操作:链式语法在对集合进行操作时非常方便。
常见的集合操作包括过滤、映射、排序等。
例如,我们有一个整数列表,我们想要获取其中大于10的偶数,并按照从大到小的顺序进行排序:List<Integer> numbers = Arrays.asList(1, 5, 10, 15, 20, 25);List<Integer> result = numbers.stream().filter(n -> n % 2 == 0).filter(n -> n > 10).sorted(Comparator.reverseOrd er()).collect(Collectors.toList()); System.out.println(result); // 输出:[20, 15]3. 对象构建:使用链式语法可以简化对象的构建过程,特别是当对象有多个属性需要设置时。
例如,我们有一个Person类,包含姓名、年龄和性别属性,我们可以通过链式语法一次性设置多个属性:Person person = new Person().setName("张三").setAge(25).setGender("男");System.out.println(person); // 输出:Person{name='张三', age=25, gender='男'}4. 文件操作:在Java中,我们经常需要进行文件读写操作。
Java中LinkList用法概述L i nk Li st(链表)是一种常见的数据结构,它是由一系列节点组成的,每个节点包含了数据以及指向下一个节点的指针。
在J av a中,L i nk Li s t是一个具有动态大小的集合,可以在任意位置插入、删除元素。
创建LinkLi st创建一个Li nk Li st对象非常简单,只需使用Ja va提供的L i nk ed Li st类即可。
下面是创建一个Li n kL is t对象的示例代码:```j av aL i nk ed Li st<S tr ing>li nk Li st=n ew Lin k ed Li st<>();```LinkL ist的常用方法L i nk Li st提供了丰富的方法来操作链表的元素,下面介绍一些常用的方法:1.添加元素-`ad dF ir st(E e)`:在链表的开头插入元素。
-`ad dL as t(Ee)`:在链表的末尾插入元素。
-`ad d(in ti nd ex,Ee)`:在指定位置插入元素。
例如,如下代码演示了如何向链表中添加元素:```j av al i nk Li st.a dd Fi rst("A pp le");l i nk Li st.a dd La st("Ba na na");l i nk Li st.a dd(1,"O r an ge");```2.获取元素-`ge tF ir st()`:获取链表的第一个元素。
-`ge tL as t()`:获取链表的最后一个元素。
-`ge t(in ti nd ex)`:获取指定位置的元素。
以下代码展示了如何获取链表中的元素:```j av aS t ri ng fi rs tE le men t=l in kL is t.ge tFi r st();S t ri ng la st El em ent=li nk Li st.g et Las t();S t ri ng el em en tA tIn d ex=l in kL is t.get(1);```3.删除元素-`re mo ve Fi rs t()`:删除链表的第一个元素。
Java链表(LinkNode)的简单操作:初始化,遍历,插⼊,删除等由于java中没有结构体,所以⽤⼀个类来定义链表,代码如下主要包括⼀个data,还有⼀个指向后⾯⼀个节点的next重写了toString函数,返回你想要的数据定义链表的类:package LinkNode;public class LinkNode {public String data;public LinkNode next;public String getData(){return data;}public void setData(String data){this.data=data;}public LinkNode getNext(){return next;}public void setNext(LinkNode next){this.next=next;}public LinkNode(String data,LinkNode next){super();this.data=data;this.next=next;}public LinkNode(){super();}@Overridepublic String toString(){return "data:"+data+" next->"+next;}}1.初始化链表:public static void initLinkNode(LinkNode L){L.setData("#");L.setNext(null);}2.遍历链表,返回链表的长度public static int traverse(LinkNode L){LinkNode p = L;int count = 1;while(p.next!=null){p = p.next;count++;}return count;}3.把链表L的data转化为StringBuffer输出,输出结果为字符串public static StringBuffer outputLinkNode(LinkNode L){StringBuffer str = new StringBuffer("");LinkNode p = L;for(@SuppressWarnings("unused")int i=0;;){str.append(p.data);if(p.next!=null){p = p.next;}else{break;}}return str;}4.在链表L的尾部插⼊⼀个节点,值为datapublic static void insertLinkNode(LinkNode L,String data){LinkNode p = L;LinkNode q = new LinkNode();for(@SuppressWarnings("unused")int i=0;;){if(p.next==null){q.setData(data);q.setNext(null);p.setNext(q);System.out.println("Insert "+data+" success.");break;}else{p = p.next;}}}5.删除第n个节点(从0开始)public static void deleteLinkNode(LinkNode L,int n){int count = 1;LinkNode p = L;for(@SuppressWarnings("unused")int i;;){if(count == n){p.setNext(p.next.next);break;}else{count++;p = p.next;}}}6.从index=n开始遍历,如果后⾯出现str,则返回true否则返回false public static int lastIndex(LinkNode L,String str){LinkNode p = L;int flag = 0;for(int i=0;i<traverse(L);i++){if(p.data==str){//System.out.println(i);flag = i;}p = p.next;}return flag;}测试程序:package LinkNode;public class Quarrel extends Method{public static void main(String[] args){LinkNode L = new LinkNode();System.out.println("初始化:");initLinkNode(L);System.out.println(L.toString());System.out.println("插⼊节点:"); insertLinkNode(L,"R");insertLinkNode(L,"R");insertLinkNode(L,"L");insertLinkNode(L,"L");insertLinkNode(L,"R");insertLinkNode(L,"L");System.out.println(L.toString());int count = traverse(L);System.out.println("节点个数:"+count); StringBuffer str = outputLinkNode(L);System.out.println(str);//最后⼀个L的位置int lastindex = lastIndex(L,"L");System.out.println("最后⼀个L的位置:"+lastindex); System.out.println("删除⼀个节点"); deleteLinkNode(L,2);count = traverse(L);System.out.println("节点个数:"+count);str = outputLinkNode(L);System.out.println(str);System.out.println(L.toString());}}结果如下:。
一、题目要求:用Java语言实现单链表的基本操作,并实现集合的交、并和差运算。
二、程序功能定义:1、输出两个集合的交集,即找出两个集合的相同元素。
2、输出两个集合的并集,即把两个集合的全部元素不重复的加起来。
3、输出两个集合的差集,即从一个集合中找出另一个集合里没有的元素。
三、设计思路:程序1:单链表结点public class Node<T> //单链表结点类,T指定结点的元素类型{public T data; //数据域,保存数据元素public Node<T> next; //地址域,引用后继结点public Node(T data, Node<T> next) //构造结点,data指定数据元素,next指定后继结点{this.data = data;this.next = next;}public Node(){this(null, null);}}程序2:import java.util.ArrayList;public class SinglyList<T>{public Node<T> head;public int length;//以上为默认构造方法,构造空单链表public static ArrayList<String> union=new ArrayList<String>();public SinglyList(){this.head = new Node<T>();}//以上为构造单链表public SinglyList(T[] element){this(); //创建空单链表,只有头结点this.length = element.length;Node<T> rear = this.head; //rear指向单链表最后一个结点for (int i = 0; i < element.length; i++)//若element==null,跑出空对象异常;element.length==0时,构造空链表{rear.next = new Node<T>(element[i], null); //创建结点链入rear结点之后rear = rear.next; //rear指向性的链尾结点}}public String toString(){String str = "(";Node<T> p = this.head.next;while (p != null){str += p.data.toString();if (p.next != null){str += ",";} //不是最后一个结点时,后加分隔符p = p.next;}return str + ")"; //空表返回()}public String addAll(SinglyList list){Node<T> p = this.head.next;String str = "(";while (p != null){Node<T> q = list.head.next;while (q != null){if ( p.data.toString().equals(q.data.toString())) //集合的元素值相等{if (!str.equals("(")){str += ",";} //用逗号间隔str += p.data.toString();this.union.add(p.data.toString()) ;}q = q.next;}p = p.next;}return str + ")";}//以上为求交集过程。
链表1 定义链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。
由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。
链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向明上一个或下一个节点的位置的链接("links")。
链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的访问往往要在不同的排列顺序中转换。
而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。
链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。
链表有很多种不同的类型:单向链表,双向链表以及循环链表。
2 结构2.1 单向链表链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。
这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。
一个单向链表的节点被分成两个部分。
第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。
单向链表只可向一个方向遍历。
链表最基本的结构是在每个节点保存数据和到下一个节点的地址,在最后一个节点保存一个特殊的结束标记,另外在一个固定的位置保存指向第一个节点的指针,有的时候也会同时储存指向最后一个节点的指针。
一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。
Deque Java用法什么是Deque?在Java中,Deque(Double Ended Queue)是双端队列的缩写,是一种具有队列和栈的特性的数据结构。
Deque允许我们在队列的两端进行插入和删除操作,因此可以在队列的任意一端添加或删除元素。
Deque接口是Java集合框架中的一部分,在Java 6中被引入。
它是Queue和Stack的一种扩展,提供了更多的操作方法。
Deque的实现类在Java中,Deque接口有两个主要的实现类:1.ArrayDeque:基于数组实现的Deque,没有容量限制,可以动态增长。
2.LinkedList:基于链表实现的Deque,没有容量限制,可以动态增长。
这两个实现类都实现了Deque接口,提供了相同的方法和功能,只是底层实现不同。
选择哪个实现类取决于具体的需求和性能要求。
Deque的常用方法Deque接口提供了一系列方法来操作双端队列。
下面是一些常用的方法:1.添加元素的方法:–addFirst(E e):将元素插入到双端队列的开头。
–addLast(E e):将元素插入到双端队列的末尾。
–offerFirst(E e):将元素插入到双端队列的开头,并返回插入操作的结果。
–offerLast(E e):将元素插入到双端队列的末尾,并返回插入操作的结果。
2.删除元素的方法:–removeFirst():删除并返回双端队列的第一个元素。
–removeLast():删除并返回双端队列的最后一个元素。
–pollFirst():删除并返回双端队列的第一个元素,如果双端队列为空,则返回null。
–pollLast():删除并返回双端队列的最后一个元素,如果双端队列为空,则返回null。
3.获取元素的方法:–getFirst():返回双端队列的第一个元素,但不删除。
–getLast():返回双端队列的最后一个元素,但不删除。
–peekFirst():返回双端队列的第一个元素,如果双端队列为空,则返回null。
链表是一种重要的数据结构,在程序设计中占有很重要的地位。
C语言和C++语言中是用指针来实现链表结构的,由于Java语言不提供指针,所以有人认为在Java语言中不能实现链表,其实不然,Java语言比C和C++更容易实现链表结构。
Java语言中的对象引用实际上是一个指针(本文中的指针均为概念上的意义,而非语言提供的数据类型),所以我们可以编写这样的类来实现链表中的结点。
class Node {
Object data;
Node next;// 指向下一个结点
}
将数据域定义成Object类是因为Object类是广义超类,任何类对象都可以给其赋值,增加了代码的通用性。
为了使链表可以被访问还需要定义一个表头,表头必须包含指向第一个结点的指针和指向当前结点的指针。
为了便于在链表尾部增加结点,还可以增加一指向链表尾部的指针,另外还可以用一个域来表示链表的大小,当调用者想得到链表的大小时,不必遍历整个链表。
下图是这种链表的示意图:
链表的数据结构
我们可以用类List来实现链表结构,用变量Head、Tail、Length、Pointer来实现表头。
存储当前结点的指针时有一定的技巧,Pointer并非存储指向当前结点的指针,而是存储指向它的前趋结点的指针,当其值为null时表示当前结点是第一个结点。
那么为什么要这样做呢?这是因为当删除当前结点后仍需保证剩下的结点构成链表,如果Pointer指向当前结点,则会给操作带来很大困难。
那么如何得到当前结点呢,我们定义了一个方法cursor(),返回值是指向当前结点的指针。
类List还定义了一些方法来实现对链表的基本操作,通过运用这些基本操作我们可以对链表进行各种操作。
例如reset()方法使第一个结点成为当前结点。
insert(Object d)方法在当前结点前插入一个结点,并使其成为当前结点。
remove()方法删除当前结点同时返回其内容,并使其后继结点成为当前结点,如果删除的是最后一个结点,则第一个结点变为当前结点。
链表类List的源代码如下:
import java.io.*;
public class List {
/* 用变量来实现表头 */
private Node Head = null;
private Node Tail = null;
private Node Pointer = null;
private int Length = 0;
public void deleteAll() {/* 清空整个链表 */
Head = null;
Tail = null;
Pointer = null;
Length = 0;
}
public void reset() {/* 链表复位,使第一个结点成为当前结点 */
Pointer = null;
}
public boolean isEmpty() {/* 判断链表是否为空 */
return (Length == 0);
}
public boolean isEnd() {/* 判断当前结点是否为最后一个结点 */
if (Length == 0)
throw new ng.NullPointerException();
else if (Length == 1)
return true;
else
return (cursor() == Tail);
}
public Object nextNode() {/* 返回当前结点的下一个结点的值,并使其成为当前结点 */
if (Length == 1)
throw new java.util.NoSuchElementException();
else if (Length == 0)
throw new ng.NullPointerException();
else {
Node temp = cursor();
Pointer = temp;
if (temp != Tail)
return (temp.next.data);
else
throw new java.util.NoSuchElementException();
}
}
public Object currentNode() {/* 返回当前结点的值 */
Node temp = cursor();
return temp.data;
}
public void insert(Object d) {/* 在当前结点前插入一个结点,并使其成为当前结点 */
Node e = new Node(d);
if (Length == 0) {
Tail = e;
Head = e;
} else {
Node temp = cursor();
e.next = temp;
if (Pointer == null)
Head = e;
else
Pointer.next = e;
}
Length++;
}
public int size() {/* 返回链表的大小 */
return (Length);
}
/**
* 将当前结点移出链表,下一个结点成为当前结点,如果移出的结点是最后一个结点,则第一个结点成为当前结点
* */
public Object remove() {
Object temp;
if (Length == 0)
throw new java.util.NoSuchElementException();
else if (Length == 1) {
temp = Head.data;
deleteAll();
} else {
Node cur = cursor();
temp = cur.data;
if (cur == Head)
Head = cur.next;
else if (cur == Tail) {
Pointer.next = null;
Tail = Pointer;
reset();
} else
Pointer.next = cur.next;
Length--;
}
return temp;
}
private Node cursor() {/* 返回当前结点的指针 */
if (Head == null)
throw new ng.NullPointerException();
else if (Pointer == null)
return Head;
else
return Pointer.next;
}
public static void main(String[] args){/* 链表的简单应用举例 */ List a = new List();
for (int i = 1; i <= 10; i++)
a.insert(new Integer(i));
System.out.println(a.currentNode());
while (!a.isEnd())
System.out.println(a.nextNode());
a.reset();
while (!a.isEnd()) {
a.remove();
}
a.remove();
a.reset();
if (a.isEmpty())
System.out.println("There is no Node in List \n");
System.out.println("You can press return to quit\n");
try {
System.in.read();
// 确保用户看清程序运行结果
} catch (IOException e) {
}
}
}
class Node{/* 构成链表的结点定义 */
Object data;
Node next;
Node(Object d) {
data = d;
next = null;
}
}
读者还可以根据实际需要定义新的方法来对链表进行操作。
双向链表可以用类似的方法实现只是结点的类增加了一个指向前趋结点的指针。
可以用这样的代码来实现:
class Node {
Object data;
Node next;
Node previous;
Node(Object d) {
data = d;
next = null;
previous = null;
}
}
当然,双向链表基本操作的实现略有不同。
链表和双向链表的实现方法,也可以用在堆栈和队列的实现中,这里就不再多写了,有兴趣的读者可以将List类的代码稍加改动即可。