首页 技术 正文
技术 2022年11月23日
0 收藏 654 点赞 3,398 浏览 15264 个字

一、打印两个有序链表的公共部分

补充一个关于节点的链表构造方法

Node next是设置指针域

import java.io.IOException;这个是报错信息

这是两个lO流

import java.io.BufferedReader;

import java.io.InputStreamReader;

以下的代码可以实现最高效率速度读取

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

类 InputStreamReader是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。如:GBK 
  每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:  BufferedReader in= new BufferedReader(new InputStreamReader(System.in));

System.in是个字节流

InputStreamReader是个字符流和字节流之间的转换中介

BufferedReader是个字符流
整体意思就是用InputStreamReader这个中介把System.in这个字节流转换成字符流BufferedReader
这样输入的时候就可以不是一个一个字节读,而是一个一个字符读,再加上是个Buffer,效率会高很多。

public class Mylinkedlist {
class Node {
int value;
Node next; Node(int data) {
this.value = data;
}//构造方法
} private Node first; //头节点 Mylinkedlist() {
first = null;
} //插入一个节点,在头节点之后插入
void insertFirst(int value) {
Node node = new Node(value);
node.next = first;
first = node;
} //删除一个节点用tmp表示,在头节点之后进行删除
Node deleteFirst() {
Node tmp = first.next;
first = tmp.next;
return tmp;
}}

网络上很多人用的是IO流速度会比较快

本题主要是对list的使用进行考察,重点要注意的是listgenerate函数如何生成的,对于一个class内所有的方法都要加入static

import java.util.Scanner;public class Linkedlist1 {
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} private static Node listGenerator(int length, String[] numbers) {
Node head = new Node(Integer.parseInt(numbers[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(numbers[i]));
cur = cur.next;
}
cur.next = null;
return head;
} public static void printCommonPart(Node head1, Node head2) {
if (head1 == null || head2 == null) {
return;
}
while (head1 != null && head2 != null) {
if (head1.value > head2.value) {
head2 = head2.next;
} else if (head1.value < head2.value) {
head1 = head1.next;
} else {
System.out.print(head1.value + " ");
head1 = head1.next;
head2 = head2.next;
}
}
System.out.println();
} public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
sc.nextLine();
String str1 = sc.nextLine();
String[] a = str1.split(" "); Node head1 = listGenerator(num1, a); int num2 = sc.nextInt();
sc.nextLine();
String str2 = sc.nextLine();
String[] b = str2.split(" "); Node head2 = listGenerator(num2, b);
printCommonPart(head1, head2); }
}

二、删除倒数第k个节点

超时了。还是要快点学io流

import java.util.Scanner;public class Linkedlist2 {
public static class Node {
private int value;
Node next; Node(int value) {
this.value = value;
}
} public static Node listGenerate(int length, String[] number) {
Node head = new Node(Integer.parseInt(number[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(number[i]));
cur = cur.next;
}
cur.next = null;
return head;
} //num_delete是前面一个节点数倒数第4个就是正第1个
public static Node listDelete(int num_delete, Node head) {
if (head == null || num_delete < 0) return null;
else if (num_delete == 0) return head = head.next;
else {
Node cur = head;
for (int i = 0; i < num_delete - 1; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
return head;
} } public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int length = sc.nextInt();
int delete=sc.nextInt();
sc.nextLine();
String str1 = sc.nextLine();
String[] a = str1.split(" ");
Node head=listGenerate(length,a);
int num_delete=length-delete;
head=listDelete(num_delete,head);
while (head.next!=null){
System.out.print(head.value);
System.out.print(" ");
head=head.next;
}
System.out.print(head.value); }
}

对于链表学习还是看算法书实现的比较好。

注意头节点的增删问题,这个很重要。

1、查找元素

用一个计数器计数,从0开始判断当前节点的数据域是否为x,不是则next,注意最好不要修改链表的head的值,可以用cur来代替

2、插入元素

新建节点q

找到插入位置的前一个节点pre,这个很重要

q.next=pre.next;

pre.next=q;

3、删除元素

需要找到前驱节点pre

和p删除节点

pre.next=p.next;

三、删除第i个节点

很典型建议背诵

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;public class Linkedlist3 {
public static class Node {
private int value;
Node next; Node(int value) {
this.value = value;
}
} public static Node listGenerate(int length, String[] number) {
Node head = new Node(Integer.parseInt(number[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(number[i]));
cur = cur.next;
}
cur.next = null;
return head;
} public static Node removeMidNode(Node head, int m) {
Node cur = head;
if (head == null || m < 1) return null;
else if (m == 1) return head = head.next;
else {
while (--m != 1) {
cur = cur.next;
}
cur.next = cur.next.next;
return head;
}
} public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] number = bf.readLine().split(" ");
int length = Integer.parseInt(number[0]);
int delete = Integer.parseInt(number[1]);
String[] a = bf.readLine().split(" ");
Node head = listGenerate(length, a);
head=removeMidNode(head,delete);
StringBuilder str = new StringBuilder();
while (head!= null) {
str.append(head.value);
str.append(" ");
head = head.next;
}
System.out.println(str.toString()); }}

四、反转链表

public static Node reverseList(Node head) {
Node pre = null;
Node next = null;//pre用来保存先前结点、next用来做临时变量
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next; }
return pre;
}

这段代码很值得学习,首先明确概念引用类型的声明变量都是地址,所以除非new的内容都只是地址值。

1->2->3->4

pre节点存储的是新节点的首地址,next存储是要反转的下一个节点地址。

首先把next赋值头节点的下一个节点,所以指向的值是2。

然后把头节点的下一个节点的指向变为pre空节点。

再将pre进行赋值,赋值头节点,因此现在的反转是1->0,也就是pre->null

最后将头节点赋值,赋值next曾经的下一个节点。

还要注意学习一下双链表的构建

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;public class Linkedlist4 {
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} //双向链表
public static class DoubleNode {
int value;
DoubleNode last;
DoubleNode next; DoubleNode(int value) {
this.value = value;
}
} //单向链表的反转
public static Node listGenerate(int length, String[] number) {
Node head = new Node(Integer.parseInt(number[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(number[i]));
cur = cur.next;
}
cur.next = null;
return head;
} //双向链表的反转
public static DoubleNode D_listGenerate(int length, String[] number) {
DoubleNode head = new DoubleNode(Integer.parseInt(number[0]));
DoubleNode cur = head;
for (int i = 1; i < length; i++) {
cur.next = new DoubleNode(Integer.parseInt(number[i]));
cur.next.last = cur;
cur = cur.next;
}
cur.next = null;
return head;
} public static Node reverseList(Node head) {
Node pre = null;
Node next = null;//pre用来保存先前结点、next用来做临时变量
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
} public static DoubleNode D_reverseList(DoubleNode head) {
DoubleNode pre = null;
DoubleNode next = null;
while (head != null) {
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
} public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int length=Integer.parseInt(bf.readLine());
String[] number = bf.readLine().split(" ");
int length2=Integer.parseInt(bf.readLine());
String[] number2 = bf.readLine().split(" ");
Node head = listGenerate(length, number);
DoubleNode head2 = D_listGenerate(length2, number2);
head = reverseList(head);
head2=D_reverseList(head2);
StringBuilder str = new StringBuilder();
StringBuilder str2 = new StringBuilder();
while (head != null) {
str.append(head.value).append(" ");
head = head.next;
}
System.out.println(str.toString()); while (head2 != null) {
str2.append(head2.value).append(" ");
head2 = head2.next;
} System.out.println(str2.toString());
}}

五、反转部分单向链表

主要是找到反转的前一个节点和后一个节点,考虑到首节点可能要变化的问题。

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;public class Linkedlist5 {
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} public static Node listGenerate(int length, String[] num) {
Node head = new Node(Integer.parseInt(num[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(num[i]));
cur = cur.next;
}
cur.next = null;
return head;
} public static Node reverseNode(Node head, int from, int to) {
int len = 0;
Node node1 = head;
Node fPre = null;
Node tPos = null;
while (node1 != null) {
len++;
fPre = len == from - 1 ? node1 : fPre;
tPos = len == to + 1 ? node1 : tPos;
node1= node1.next;
}
if (from > to || from < 1 || to > len) {
return head;
}
node1 = fPre == null ? head : fPre.next;
Node pre=tPos;//为转换后的头节点
Node next=null;
while (node1!=tPos){
next=node1.next;
node1.next=pre;
pre=node1;
node1=next;
}
if (fPre != null) {
fPre.next = pre;
return head;
}
return pre; } public static void main(String[] args) throws IOException {
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
int length=Integer.parseInt(bf.readLine());
String[] num=bf.readLine().split(" ");
String[] num2=bf.readLine().split(" ");
int from=Integer.parseInt(num2[0]);
int to=Integer.parseInt(num2[1]);
Node head=listGenerate(length,num);
head=reverseNode(head,from,to);
StringBuilder str=new StringBuilder();
while (head!=null){
str.append(head.value).append(" ");
head=head.next;
}
System.out.println(str.toString());
}}

六、环型链表约瑟夫问题

注意环型链表的删除

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Linkedlist6 {
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} public static Node josephusKill(Node head,int m){
if(head==null||head.next==head||m<1){
return head;
}
Node last=head;
while(last.next!=head){
last=last.next;
}
int count=0;
while(head!=last){
count++;
if(count==m){
last.next=head.next;
count=0;
}
else{
last=last.next;
}
head=last.next;
}
return head; } public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] parameters = bufferedReader.readLine().split(" ");
int l = Integer.parseInt(parameters[0]);
int m = Integer.parseInt(parameters[1]);
Node head = new Node(1);
Node cur = head;
for (int i = 2; i <= l; i++) {
cur.next = new Node(i);
cur = cur.next;
}
cur.next = head;
head = josephusKill(head, m);
System.out.println(head.value);
}}import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Linkedlist6 {
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} public static Node josephusKill(Node head,int m){
if(head==null||head.next==head||m<1){
return head;
}
Node last=head;
while(last.next!=head){
last=last.next;
}
int count=0;
while(head!=last){
count++;
if(count==m){
last.next=head.next;
count=0;
}
else{
last=last.next;
}
head=last.next;
}
return head; } public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] parameters = bufferedReader.readLine().split(" ");
int l = Integer.parseInt(parameters[0]);
int m = Integer.parseInt(parameters[1]);
Node head = new Node(1);
Node cur = head;
for (int i = 2; i <= l; i++) {
cur.next = new Node(i);
cur = cur.next;
}
cur.next = head;
head = josephusKill(head, m);
System.out.println(head.value);
}}

七、给定一个链表,请判断该链表是否为回文结构

import java.util.Stack;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;public class Linkedlist7 {
public static Stack<Integer> st=new Stack<>();
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} public static Node listGenerate(int length,String[] num){
Node head=new Node(Integer.parseInt(num[0]));
st.push(head.value);
Node cur=head;
for(int i=1;i<length;i++){
cur.next=new Node(Integer.parseInt(num[i]));
cur=cur.next;
st.push(cur.value);
}
cur.next=null;
return head;
} public static void main(String[] args) throws IOException {
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
int length=Integer.parseInt(bf.readLine());
String[] num=bf.readLine().split(" ");
Node head=listGenerate(length,num);
int flag=0;
for(int i=0;i<length;i++){
if(head.value!=st.pop()) {
flag=1;
System.out.println("false");
break;
}
head=head.next;
}
if(flag==0) System.out.println("true");
}}

八、将单链表按某值划分为左边小、中间相等、右边大的形式

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;class Node{
public int value;
public Node next;
public Node(int value){
this.value = value;
}
}
class ListPartition{
public static Node listPartition(Node head,int pivot){
if(head == null || head.next == null)
return head;
//统计链表长度
int i = 0;
Node node = head;
while(node != null){
i++;
node = node.next;
}
//创建数组,并填充
Node[] arr = new Node[i];
node = head;
for(i = 0;i < arr.length;i++){
arr[i] = node;
node = node.next;
}
//对数组进行partition
partitionArr(arr,pivot);
//将数组组合成链表
for(i = 1; i < arr.length; i++){
arr[i-1].next = arr[i];
}
//最后一个的指向
arr[i-1].next = null;
return arr[0];
}
public static void partitionArr(Node[] arr,int pivot){
int less = -1;
int more = arr.length;
int index = 0;
while(index < more){
if(arr[index].value < pivot){
swap(arr,index++,++less);
}else if(arr[index].value > pivot){
swap(arr,index,--more);
}else{
index++;
}
} }
public static void swap(Node[] arr, int i,int j){
Node temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
public class Main{
//创建链表
private static Node createNode(String[] str,int n){
Node head = new Node(Integer.parseInt(str[0]));
Node node = head;
for(int i=1;i<n;i++){
Node newNode = new Node(Integer.parseInt(str[i]));
node.next = newNode;
node = newNode;
}
return head;
}
//打印列表
private static void printList(Node node){
StringBuilder builder = new StringBuilder();
while (node != null){
builder.append(node.value).append(" ");
node = node.next;
}
System.out.println(builder.toString());
}
//主函数部分
public static void main(String[] args) throws IOException{
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//创建第一个链表
String[] s = input.readLine().split(" ");
int n = Integer.parseInt(s[0]);
int pivot = Integer.parseInt(s[1]);
String[] strings1 = input.readLine().split(" ");
Node list1 = createNode(strings1,n);
//要操作的函数
Node node = ListPartition.listPartition(list1,pivot);
printList(node);
}
}

这个题目没做出来,很奇怪,我理解就是排序再合成一个链表,但是还是报错。

这个用例有个重要的方法叫做partition,大概就是类似与快速排序的过程  。

九、两个单链表生成相加链表

这个题目需要注意直接相加两个数,java 的整数类型int接受不了,因此需要用到堆栈。并且使用进位的方式来进行记录

变成小学加法题目来做

import java.util.Stack;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;public class Mylinkedlist9 {
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} //堆栈存放整数
public static Stack<Integer> st1 = new Stack<>();
public static Stack<Integer> st2 = new Stack<>(); public static Node listGenerate(Stack<Integer> st1, Stack<Integer> st2) {
//定义接受出栈的元素,cur为进位
Node head = null;
Node cur = null;
int num1 = 0;
int num2 = 0;
int sum = 0;
Boolean ca = false;
while (!st1.isEmpty() || !st2.isEmpty()) {
if (!st1.isEmpty()) {
num1 = st1.pop();
} else num1 = 0;
if (!st2.isEmpty()) {
num2 = st2.pop();
} else num2 = 0;
sum = num1 + num2;
if (ca) {
sum++;
ca=false;
} if (sum >= 10) {
ca = true;//需要进位
sum = sum - 10;
}
head = new Node(sum);
head.next = cur;
cur = head;
}
if (ca) {
head = new Node(1);
head.next = cur;
}
return head;
} public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] num1 = bf.readLine().split(" ");
String[] num2 = bf.readLine().split(" ");
String[] num3 = bf.readLine().split(" ");
int n = Integer.parseInt(num1[0]);//记录长度
int m = Integer.parseInt(num1[1]);//记录第二个链表的长度
for (int i = 0; i < n; i++) {
st1.push(Integer.parseInt(num2[i]));
}
for (int i = 0; i < m; i++) {
st2.push(Integer.parseInt(num3[i]));
}
Node head = listGenerate(st1, st2);
StringBuilder sb = new StringBuilder();
while (head != null) {
sb.append(head.value).append(" ");
head = head.next;
}
System.out.println(sb.toString());
}}

十、将单链表的每K个节点之间逆序

我的方法有点投机取巧了,但也能通过==还是看看书上的方法。

最近的题目感觉有些相似,可以考虑跳过了。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.Buffer;
import java.util.Stack;public class Mylinkedlist10 {
//节点定义
public static class Node {
int value;
Node next; Node(int value) {
this.value = value;
}
} //生成链表
public static Node listGenerate(int length, String[] num) {
Node head = new Node(Integer.parseInt(num[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(num[i]));
cur = cur.next;
}
cur.next = null;
return head;
} public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int length = Integer.parseInt(bf.readLine());
String[] str1 = bf.readLine().split(" ");
int reverse = Integer.parseInt(bf.readLine());
Node head = listGenerate(length, str1);
Stack<Integer> stack = new Stack<>();
int time = length / reverse;
String[] str2 = new String[reverse];
//反转链表
Node cur = head;
for (int i = 0; i < time; i++) {
for (int j = 0; j < reverse; j++) {
stack.push(cur.value);
cur = cur.next;
}
for (int j = 0; j < reverse; j++) {
str1[j + reverse * i] = "" + stack.pop();
}
}
StringBuilder str = new StringBuilder();
for (int i = 0; i < length; i++) {
str.append(str1[i]).append(" ");
}
System.out.println(str.toString()); }}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,991
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,506
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,349
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,134
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,766
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,844