常考链表操作

1. 链表反转

改变指针方向,将头结点改为尾节点。本次给出全部代码,后来只给部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
class Node{

int value;

​ Node next=null;

public Node(int value){

this.value=value;

​ }

}

public class linkedlisttest {

​ Node head=null;

public Node getHead() {

return head;

​ }

public void insert(int data){

​ Node newNode=new Node(data);

if(head==null){

​ head=newNode;

return;

​ }

​ Node tmp=head;

while(tmp.next!=null){

​ tmp=tmp.next;

​ }

​ tmp.next=newNode;





​ }

public void printList() {

​ Node tmp = head;



while (tmp != null) {

​ System.out.print(tmp.value+" ");

​ tmp = tmp.next;



​ }

​ }

//链表反转

public void reverseListNode(Node head) {

​ Node pReverseHead=head;//设置反转后的头结点

​ Node pNode=head;//当前节点

​ Node pPrev=null;//前一个节点

while(pNode!=null){

/*

​ * 例如i,m,n

​ 由于反转需要改变指针的指向,但是一旦改变了指针的指向就没有指针指向下一个数,所以需要在改变i到m的指针顺序时

​ ,提前将下一个数存起来。

​ */

​ Node pNext=pNode.next;//存储下一个节点

if(pNext==null)

​ pReverseHead=pNode;//令当前节点为反转链表的头结点



​ pNode.next=pPrev;//将当前节点的下一个节点设为前一个节点



​ pPrev=pNode;//前一个节点为当前节点

​ pNode=pNext;//当前节点向下走

​ }

this.head=pReverseHead;

​ }

public static void main(String[] args) {

​ linkedlisttest l=new linkedlisttest();

​ l.insert(1);

​ l.insert(2);

​ l.insert(3);

​ l.printList();

​ System.out.println("\n链表反转:");

​ l.reverseListNode(l.getHead());

​ l.printList();



​ }



}

运行结果:

img

2 .链表从尾到头输出

直接递归,等到后来二叉树三种遍历也是这个思想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public void printListReversely(Node plistHead){

if(plistHead!=null){

​ printListReversely(plistHead.next);

​ System.out.print(plistHead.value+" ");



​ }



​ }

主函数:

public static void main(String[] args) {

​ linkedlisttest l=new linkedlisttest();

​ l.insert(1);

​ l.insert(2);

​ l.insert(3);

​ l.printList();

​ System.out.println("\n链表从尾到头输出:");

​ l.printListReversely(l.getHead());





​ }

输出结果:

img

3. 判断链表是否有环

定义两个指针,一个快指针,一个慢指针,两个指针同时移动,快指针每次移动两步,慢指针移动一步,每次都比较,直到快指针等于慢指针为止。(fast先到底部为null则为无环链表)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public boolean Isloop(Node head){

​ Node fast=head;

​ Node slow=head;

if(fast==null){

return false;

​ }

while(fast!=null&&fast.next!=null){

​ fast=fast.next.next;

​ slow=slow.next;

if(fast==slow){

return true;

​ }

​ }





return (fast!=null&&fast.next!=null);

​ }

4. 如何删除重复元素

对链表进行双重遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
public void deleteDuplecate(Node head){
Node p=head;
while(p!=null){
Node q=p;
while(q.next!=null){
if(p.value==q.next.value){
q.next=q.next.next;
}else
q=q.next;
}
p=p.next;
}
}

运行结果:

img

9.4 如何找到倒数第k个元素

设置两个指针,一个正常从头到尾遍历,另一个先前移k-1步然后依次遍历,当这个快指针先到达尾部,则另一个指针的位置就是倒数第k个元素。

主函数:

img

输出结果:

img

9.5 判断两个链表是否相交

如果相交则有相同的尾节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public boolean isIntersect(Node h1,Node h2){

if(h1==null||h2==null){

return false;

​ }

​ Node tail=h1;

​ Node tail2=h2;

while(tail.next!=null){

​ tail=tail.next;

​ }

while(tail2.next!=null){

​ tail2=tail2.next;

​ }

return tail==tail2;

​ }

9.6 链表排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public Node orderlist() {

​ Node nextNode = null;

int temp = 0;

​ Node curNode = head;

while (curNode.next != null) {

​ nextNode = curNode.next;

while (nextNode != null) {

if (curNode.data > nextNode.data) {

​ temp = curNode.data;

​ curNode.data = nextNode.data;

​ nextNode.data = temp;

​ }

​ nextNode = nextNode.next;

​ }

​ curNode = curNode.next;

​ }

return head;

​ }
-------------本文结束感谢您的阅读-------------
0%