3.如何在单向链表中找出第k个元素?
- 方法1:先把链表遍历一遍,得到链表的总长度 getLength(),得到size后,从链表的第一个开始遍历 (size-index)个,就可以得到(遍历两次)
public static Node findNode(Node head,int index){
if(head.next == null){//判空
return null;
}
int size = getLength(head);//第一次遍历,得到链表长度
//第二次遍历到 size-index位置,就是我们倒数第k个节点位置
if (index <= 0 || index > size) {//先对index进行校验
return null;
}
Node curr = head.next;//定义辅助变量,for循环定位到倒数的index
for(int i=0;i<size-index;i++){
curr = curr.next;
}
return curr;
}
/**获取单链表的节点个数(不考虑头节点)
* @param head 链表的头节点
* @return 节点的个数
*/
public static int getLength(Node head) {
if (head.next == null) {
return 0;
}
int length = 0;
Node cur = head.next;//辅助变量,没有统计头节点
while (cur != null) {
length++;
cur = cur.next;
}
return length;
}
- 方法2:倒数第k个节点与最后一个节点的距离是k-1,设置两个指针,让其中一个指针比另一个指针先走k-1步,然后两个指针同时移动,那么在快的指针到达结尾时,慢的指针到达的位置正好是倒数第k个。
public class findKelem {
public static Node1 method(Node1 head, int k) {
if (k < 0) {
return null;
}
Node1 p1 = head;
Node1 p2 = head;
for (int i = 0; i < k && p1 != null; ++i) {
p1 = p1.next;
}
if(p1==null) {//不注释掉这一部分在输出顺数第一个数据时会报数组越界
System.out.print("p1 is null!");
return null;
}
while (p1 != null) {
p1 = p1.next;
p2 = p2.next;
}
if (p2 == null)
System.out.println(head.data);
return p2;
}
public static void main(String[] args) {
Node1 node1 = new Node1(1);
Node1 node2 = new Node1(2);
Node1 node3 = new Node1(3);
Node1 node4 = new Node1(4);
Node1 node5 = new Node1(5);
Node1 node6 = new Node1(6);
LinkedList linkedList = new LinkedList();
linkedList.add(node3);
linkedList.add(node1);
linkedList.add(node2);
linkedList.add(node5);
linkedList.add(node6);
linkedList.add(node4);
findKelem test = new findKelem();
Node1 result = test.method(linkedList.getHead(), 2);
System.out.println(result.data);
}
}
class LinkedList{//定义链表,并实现添加节点的功能
private Node1 head = new Node1(0);
public Node1 getHead() {
return head;
}
public void add(Node1 node){//添加节点
Node1 temp = head;
boolean flag = false;
while (true) {
if (temp.next == null) {
break;
}
if(temp.next.data>node.data){
break;
}else if(temp.next.data==node.data){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
System.out.println("准备插入的节点已经存在,不能再次添加该"+node.data+"节点");
}else {
node.next = temp.next;
temp.next = node;
}
}
}
class Node1 {//定义节点
Node1 next = null;
int data;
public Node1(int data) {
this.data = data;
}
}