总结
在一些问题上本人并没有去运行(返回的是Node类型的),不过与返回值类型无关,无论是方法的调用和传递参数都是可以的(本类的话,非本类的话就static)。
当然也有其他的问题像寻找公共子节点和回文序列的问题,都有涉及栈(以及其他的问题)的知识,就不在此发表了。
合并链表问题
问题一 合并两个有序列表
逻辑:创建一个新链表(娅节点起始点),两个链表循环连接这个新建的链表(有序,判断大小),直到有一个为空的时候,另一个链表直接连接到新链表。
//合并两个有序列表
public Node mergeTwoLists(Node list1, Node list2) {
//设置一个哑节点
Node node = new Node(0);
Node current = node;
//循环节点直到某个链表为null时,跳出循环
while (list1 != null && list2 != null) {
if (list1.data <= list2.data) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
current = current.next;
}
//把剩余的节点直接进行链接上
current.next = list1 != null ? list1 : list2;
return node.next;
}
问题二 合并k个链表
逻辑:就是利用循环和两链表合并,每一次产生的新链表都参与两个链表的合并。(表述不是太清除上代码)
//合并k个链表
public Node mergeLists(Node[] lists){
//设置一个空链表
Node res = null;
//用增强for循环,调用两两链表连接的方法。
for (Node list : lists) {
res = mergeTwoLists(res, list);
}
return res;
}
双指针问题
问题一 寻找中间节点(懒,还是直接粘贴过来)
//双指针专题,就是同时有两个指针来进行操作。
//问题yi寻找中间节点。奇数时找的是中间节点,偶数时找的是中间后边的一个节点。
public void middleNode(){
//先定义两个开始的指针,一快一慢
Node slow = head,fast = head;
//然后开始判断什么时候快的结束,慢的也就是中间节点
while (fast != null &&fast.next != null){
//快的一次性进两个格子,慢的一次进一个格子
slow = slow.next;
fast = fast.next.next;
}
//最后输出中间的节点的数据。
System.out.println(slow.data);
}
寻找第k个元素,太简单(也就在遍历的基础上加上限定条件
//寻找第K个元素
public void lengthK(int K){
int length = 1;
Node current = head;
while (current != null ){
length++;
current = current.next;
if (K == length){
System.out.println(current.data);
break ;
}
}
}
旋转链表(不是倒叙,是把最后一个转到第一个!)
逻辑:判断头节点,和k的值是否为空,获取链表的长度,快指针先走k个单位,之后快慢指针一起走,直到快指针到终节点,慢节点的下一节点为空,快节点的尾结点连接头节点。
不会,运行不出来!!!!!!!!!!!!出来了,可以在该方法里面进行书写遍历,调用其他遍历方法的时候遍历输出的时候就会出现问题了。(总结:遍历输出最好是调用外面输出的方法)
//链表的旋转,输入旋转的次数
public void rotateRight(int k){
if (head ==null||k ==0){
System.out.println("请在返回内输入");
return;
}
//设置一块一慢的指针
Node temp = head;
Node fast = head;
Node slow = head;
int len = 0;
//求链表的长度
while (head != null){
head =head.next;
len++;
}
if (k % len ==0){
System.out.println("链表长度和旋转次数相等");
return;
}
while ((k % len) >0){
k--;
fast = fast.next;
}
while (fast.next != null){
fast = fast.next;
slow = slow.next;
}
Node newNode = slow.next;
slow.next = null;
fast.next = temp;
head = newNode;
while (head != null) {
System.out.print(head.data + " ");
head = head.next;
}
}
删除链表元素
问题,删除问题都是一摸一样的,逻辑都是循环到某个节点进行删除,也只有描述可能有些变化。
删除重复元素的话也仅仅只是删除有序的,无序的话本人也思考了一下,一下是思考的逻辑。
逻辑:两个for循环来寻找重复的节点(不要重复节点的),并记录下来,从后面往前删除。(但是本人感觉该过程还是非常的麻烦的,也仅仅只是想了一下)
删除相关的代码。
//删除链表的某个节点
public void deletePosition(int position){
//删除节点为头结点时
if (position == 1){
head = head.next;
}else {
//删除节点为非头节点,以及有其他情况时。
Node current = head;
int count = 1;
while (current != null && count < position - 1) {
current = current.next;
count++;
}
if (current != null) {
current.next = current.next.next;
} else {
//在非循序范围内的其他情况
System.out.println("请在允许范围内进行");
}
}
}