赞
踩
本篇博客只是简单实现单链表(不带头节点),此类链表头节点会改变,面试遇到的会比较多。此外,只是简单的实现单链表,和原码有很大差距,目的是为了通过简单的实现单链表,对链表的各种操作更加熟悉。以便以后刷链表的题更加的得心应手。
目录
- public class MySingleList {
- //写一个内部类ListNode,表示单链表的节点
- static class ListNode{
- public int vale;//节点里面的值域
- public ListNode next;//节点里面放下一个节点的地址域
- //写一个构造方法
- public ListNode(int vale) {
- this.vale = vale;
- }
- }
- public ListNode head;//头节点
-
- //这里用比较low的方法先创建一个链表,以便学习。
- // 下面会写add方法,到时候可以拿add方法创建一个链表
- public void creatList(){
- ListNode list1 = new ListNode(20);
- ListNode list2 = new ListNode(22);
- ListNode list3 = new ListNode(10);
- ListNode list4 = new ListNode(01);
- list1.next = list2;
- list2.next = list3;
- list3.next = list4;
- this.head = list1;
- }
- //遍历打印单链表
- public void display(){
- ListNode cur = this.head;
- while(cur != null){
- System.out.print(cur.vale+" ");
- cur = cur.next;
- }
- System.out.println();
- }
- //链表节点个数
- public int size(){
- int count = 0;
- ListNode cur = this.head;
- while(cur != null){
- count++;
- cur = cur.next;
- }
- return count;
- }
- //头插法
- public void addFirst(int data){
- ListNode node = new ListNode(data);
- node.next = this.head;
- head = node;
- }
- // 尾插法
- public void addLast(int data){
- ListNode node = new ListNode(data);
- if(head == null){
- head = node;
- }else{
- ListNode cur = this.head;
- while (cur.next != null){
- cur = cur.next;
- }
- cur.next = node;
- }
- }
- //任意位置插入,第一个数据节点为0号下标
- public void addIndex(int index,int data){
- if(index<0 || index > this.size()){
- throw new PosWrongFulException("index位置不合法");
- }
- if(index == 0){
- addFirst(data);
- return;
- }
- if(index == this.size()){
- addLast(data);
- return;
- }
- ListNode cur = findIndexSubOne(index);
- ListNode node = new ListNode(data);
- node.next = cur.next;
- cur.next = node;
- }
- private ListNode findIndexSubOne(int index){
- ListNode cur = this.head;
- while (index-1 != 0){
- cur = cur.next;
- index--;
- }
- return cur;
- }
- //查找是否包含关键字key是否在单链表当中
- public boolean conains(int key){
- ListNode cur = head;
- while(cur != null){
- if(cur.vale == key){
- return true;
- }
- cur = cur.next;
- }
- return false;
- }
- // 删除第一次出现关键字为key的节点
- public void remove(int key){
- if(head.vale == key){
- head = head.next;
- return;
- }
- ListNode cur = findPrevOfKey(key);
- if(cur == null){
- System.out.println("没有你要删除的值");
- return;
- }
- cur.next = cur.next.next;
- }
- private ListNode findPrevOfKey(int key){
- ListNode cur = head;
- while(cur.next != null){
- if(cur.next.vale == key){
- return cur;
- }
- cur = cur.next;
- }
- return null;
- }
- // 删除所有值为key的节点
- public void removeAllKey(int key){
- ListNode pre = head;
- ListNode cur = head.next;
- while (cur != null){
- if(cur.vale == key){
- pre.next = cur.next;
- cur = cur.next;
- }else {
- pre = cur;
- cur = cur.next;
- }
- }
- if(head.vale == key){
- head = head.next;
- }
- }
- public void clear(){
- head = null;
- }
- }
思路:创建一个cur代替head遍历这个链表,把里面的每个元素打印出来
代码
- public void display(){
- ListNode cur = this.head;
- while(cur != null){
- System.out.print(cur.vale+" ");
- cur = cur.next;
- }
- }
这里while的终止条件是cur != null,而不是cur.next != null,是因为我们要打印每个节点里面的值。如果是cur.next!=null,最后一个节点不会被打印,且如果是空链表会空指针异常。
运行结果:
(这里的creatList可以看上面写在一起的代码,就是用穷举的方法简单创建了一个单链表,很low,放下面辣)
- public void creatList(){
- ListNode list1 = new ListNode(20);
- ListNode list2 = new ListNode(22);
- ListNode list3 = new ListNode(10);
- ListNode list4 = new ListNode(01);
- list1.next = list2;
- list2.next = list3;
- list3.next = list4;
- this.head = list1;
- }
思路:和上面一样,创建一个count用来计数,遍历一下这个链表。
代码:
- //链表节点个数
- public int size(){
- int count = 0;
- ListNode cur = this.head;
- while(cur != null){
- count++;
- cur = cur.next;
- }
- return count;
- }
运行结果:
思路
代码:
- //头插法
- public void addFirst(int data){
- ListNode node = new ListNode(data);
- node.next = this.head;
- head = node;
- }
运行结果:
思路:
代码:
- public void addLast(int data){
- ListNode node = new ListNode(data);
- if(head == null){
- head = node;
- }else{
- ListNode cur = this.head;
- while (cur.next != null){
- cur = cur.next;
- }
- cur.next = node;
- }
- }
运行结果:
思路:
代码
- public void addIndex(int index,int data){
- if(index<0 || index > this.size()){
- throw new PosWrongFulException("index位置不合法");
- }
- if(index == 0){
- addFirst(data);
- return;
- }
- if(index == this.size()){
- addLast(data);
- return;
- }
- ListNode cur = findIndexSubOne(index);
- ListNode node = new ListNode(data);
- node.next = cur.next;
- cur.next = node;
- }
- private ListNode findIndexSubOne(int index){
- ListNode cur = this.head;
- while (index-1 != 0){
- cur = cur.next;
- index--;
- }
- return cur;
- }
PosWrongFulException
- public class PosWrongFulException extends RuntimeException{
- public PosWrongFulException() {
- }
-
- public PosWrongFulException(String message) {
- super(message);
- }
- }
运行结果:
思路:遍历链表
代码:
- public boolean conains(int key){
- ListNode cur = head;
- while(cur != null){
- if(cur.vale == key){
- return true;
- }
- cur = cur.next;
- }
- return false;
- }
运行结果:
思路:
假设我们现在要删除值为22这个节点,那么需要找到值为22的前一个节点,把它的next的域改为22这个节点next域指向的节点。我们可以写一个函数来找到前一个节点pre
pre.next = pre.next.next。还要考虑如果删除的是头节点,则只需要把头节点指向头节点next域指向的节点:head = head.next;
代码
- // 删除第一次出现关键字为key的节点
- public void remove(int key){
- if(head.vale == key){
- head = head.next;
- return;
- }
- ListNode cur = findPrevOfKey(key);
- if(cur == null){
- System.out.println("没有你要删除的值");
- return;
- }
- cur.next = cur.next.next;
- }
- private ListNode findPrevOfKey(int key){
- ListNode cur = head;
- while(cur.next != null){
- if(cur.next.vale == key){
- return cur;
- }
- cur = cur.next;
- }
- return null;
- }
运行结果:
思路:
假设我现在要删除所有值为20的节点,我们需要2个ListNode变量,因为如果只定义一个 cur,那么如果是连续俩个都是20的节点在一起,就会漏删。原因是当我们把第一个20节点删掉后,cur必须向后走一步,如果此时cur指向的节点的值刚好还是20就删除不了了。
我们可以先判断cur的值是否等于20,如果等于:pre的next域指向cur的next域。cur继续往后走,如果不等于,pre指向cur,cur往后走。
为什么要等cur的值不等于20时再让pre指向cur,cur再往后走。是因为如果cur的值是20,cur需要删除。如果此时另pre = cur,那么pre就不是cur的前驱了。
最后我还需要判断头节点是否等于20,如果需要删除再把头节点删除。head = head.next
代码:
- // 删除所有值为key的节点
- public void removeAllKey(int key){
- ListNode pre = head;
- ListNode cur = head.next;
- while (cur != null){
- if(cur.vale == key){
- pre.next = cur.next;
- cur = cur.next;
- }else {
- pre = cur;
- cur = cur.next;
- }
- }
- if(head.vale == key){
- head = head.next;
- }
- }
运行结果:
思路:当节点没有对象引用时就会被回收。此时只需要另头结点为空就好。
代码:
- public void clear(){
- head = null;
- }
运行结果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。