链表复习(单链表)

1.链表的概念

数据域:存储元素信息的空间(可以是数组)。
指针域:数据域的后继位置为指针域。用于存放指针。
指针/链:指针用于节点之间的联系。
节点:数据域和指针域共同组成节点。
头节点:头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义。

在这里插入图片描述

2.链表的实现

2.1 节点封装类

package com.zr.node;
/**
 * 节点封装类
 */
public class Node {
	private String nodeName;
	private Node next;//节点类
	
	//构建一个节点对象
	public Node(String nodeName) {
		this.nodeName = nodeName;
	}
	
	//返回下一个节点的对象
	public Node getNext() {
		return this.next;
	}
	
	//设置本节点的链域
	public void setNext(Node next) {
		this.next = next;
	}
	
	//返回节点的数据域
	public String getName() {
		return this.nodeName;
	}
	
	//判断是否有下一节点
	public boolean hasNext() {
		boolean is =false;
		if(this.getNext()!=null) {
			is = true;
		}
		return is;
	}
	
	

}

2.2 Link类

package com.zr.link;

import com.zr.node.Node;

public class Link {
	private Node head;//头节点
	
	public Link(String head) {
		this.head = new Node(head);
	}
	
	//追加节点
	public void addNode(String name) {
		Node p =head;//p是head的一个指针
		Node node =new Node(name);
		while(true) {
			if(!p.hasNext()) {
				p.setNext(node);
				break;
			}
			p=p.getNext();//指针后移
		}
	}
	// 删除节点
		public boolean delNode(String nodeName) {
			Node p = head;
			if (!p.hasNext()) {
				System.out.println("此表为空");
				return false;
			}
			while (p.hasNext()) {
				if (p.getNext().getName().equals(nodeName)) {
					p.setNext(p.getNext().getNext());
					break;
				}
				p = p.getNext();
			}
			System.out.println("删除节点:" + nodeName);
			return true;
		}
		/*
		 * 插入节点
		 
		 */
		public boolean insertNode(String inName,String nodeName) {
			Node p = head;
			if (!p.hasNext()) {
				addNode(nodeName);
				return true;
			}
			while (p.hasNext()) {
				if (p.getNext().getName().equals(inName)) {
					Node node=new Node(nodeName);
					node.setNext(p.getNext().getNext());
					p.getNext().setNext(node);				
					break;
				}
				p = p.getNext();
			}
			System.out.println("插入节点:" + nodeName);
			return true;
		}

		// 遍历链表
		public void display() {
			Node p = head.getNext();
			while (p != null) {
				System.out.println(p.getName());
				p = p.getNext();
			}
		}

		// 定位查找
		public void orderFind(int num) {
			Node node = head;
			int i = 0;
			System.out.println("--------开始遍历--------");
			while (node != null) {
				if (i == num) {
					System.out.println("被查找的节点为:" + node.getName());
					break;
				}
				i++;
				node = node.getNext();
			}

		}

		// 按内容查找
		public void contenFind(String name) {
			Node node = head;
			int i = 0;
			System.out.println("--------开始遍历--------");
			while (node != null) {
				if (node.getName().equals(name)) {
					System.out.println("被查找的节点为:" + node.getName());
					break;
				}
				i++;
				node = node.getNext();
			}
		}

}

3.实例

3.1 LeetCode 2 :两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers

思路:
1.创建第三个链表,指针指向这个链表(暂时),后面用于操作。
2.carry用于判断是否进位,sum(和)对十取商。如果carry等于0,即为进位
3.将sum对十取模的值放入第三个链表。

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode third =new ListNode(0);//创建第三个链表,用于存储输出的和,默认为0
        ListNode forth =third;//指针指向第三个链表
        int carry = 0;//判断是否进位

        while(l1!=null||l2!=null){
            int x =l1!=null?l1.val :0;//取得l1当前节点的值
            int y =l2!=null?l2.val:0;//取得l2当前节点的值
            int sum =x+y+carry;
            carry =sum/10;//判断是否能进位
            sum %=10;
            forth.next =new ListNode(sum);
            forth =forth.next;//指针后移
            if(l1.next!=null) l1=l1.next;//更新l1
                
            
            if(l2.next!=null) l2=l2.next;//更新l2
                
            
            if(carry==1){//若还有进位,则添加到最后一位
                forth.next =new ListNode(carry);
            }

        }
            return third.next;//因为初始位置是0,所以要输出下一位
    }
}

3.2 LeetCode 19 :删除链表的倒数第n个节点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

思路:
1.核心是双指针,设前指针(start)和后指针(end)。
2.前指针向前移动n,然后两个指针同时向前移动。当链表为null时,end的位置为倒数第n个节点。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode pre =new ListNode(0);//创建第二个链表,用于存储输出的结果,默认为0
        pre.next=head;//指针指向head
        ListNode start =pre;//将start与pre连接起来
        ListNode end = pre;//将end与pre连接起来

        while(n!=0){
            start=start.next;//节点移动
            n--;
        }
        while(start.next!=null){//前后两个节点相差n,只要将start和end同时移动,且start在最后一个位置,end就在倒数第n个位置
            start=start.next;//节点移动
            end=end.next;//节点移动
        }
        end.next=end.next.next;//删除倒数第n个节点,即连线
        return pre.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值