A implementação básica da lista vinculada está escrita em outra postagem do blog http://blog.csdn.net/a447332241/article/details/78947827
Aqui está um breve resumo de algumas perguntas comuns de teste de superfície de corrente
1. A lista vinculada é revertida
2. Imprima a lista vinculada de ponta a ponta
3. Mesclar listas vinculadas ordenadas
4. Determine se a lista vinculada tem um anel
5. Encontre o k-ésimo nó na parte inferior da lista vinculada
1. A lista vinculada é revertida
Definimos três ponteiros para registrar o nó percorrido atualmente, seu nó anterior e o próximo nó, e então percorremos sequencialmente, apontando o ponteiro do nó atual para o nó anterior.
public static Node reverse(Node head)
{
if(head==null||head.next==null)
return head;
Node cur = head.next; //当前反转结点结点
Node pre = head; //前一个结点
Node tmp=null; //中间结点 保存当前结点的下一个结点位置
while(cur!=null)
{
tmp=cur.next; //保存下一个结点
cur.next=pre; //反转指向
//向后遍历
pre=cur;
cur=tmp;
}
head.next=null;
return pre;
}
2. Imprima a lista vinculada do início ao fim
Para esse tipo de reversão de ordem, devemos pensar nas pilhas, último a entrar, primeiro a sair . Então, esse problema quer usar sua própria pilha, para o que o sistema usa a pilha, que é recursiva . Observe que a lista vinculada está vazia. A complexidade do tempo é O (n)
Nota: Não pense em inverter a lista vinculada individualmente primeiro e, em seguida, percorrer a saída, isso destruirá a estrutura da lista vinculada, não é recomendado.
//方法:从尾到头打印单链表
public static void reversePrint(Node head) {
if (head == null) {
return;
}
Stack<Node> stack = new Stack<Node>(); //新建一个栈
Node current = head;
//将链表的所有结点压栈
while (current != null) {
stack.push(current); //将当前结点压栈
current = current.next;
}
//将栈中的结点打印输出即可
while (stack.size() > 0) {
System.out.println(stack.pop().data); //出栈操作
}
}
Use a pilha do sistema, recursivamente
//使用系统的栈
public static void reversePrint1(Node head) {
if (head == null) {
return;
}
reversePrint(head.next);
System.out.println(head.data);
}
3. Mesclar listas vinculadas ordenadas
Aqui estão dois métodos 1. Semelhante à classificação por mesclagem. Preste atenção especial à situação em que ambas as listas vinculadas estão vazias e uma delas está vazia. Apenas o espaço O (1) é necessário. A complexidade do tempo é O (max (len1, len2))
// 两个参数代表的是两个链表的头结点
public Node mergeLinkList(Node head1, Node head2) {
if (head1 == null && head2 == null) { // 如果两个链表都为空
return null;
}
if (head1 == null) {
return head2;
}
if (head2 == null) {
return head1;
}
Node head; // 新链表的头结点
Node current; // current结点指向新链表
// 一开始,我们让current结点指向head1和head2中较小的数据,得到head结点
if (head1.data < head2.data) {
head = head1;
current = head1;
head1 = head1.next;
} else {
head = head2;
current = head2;
head2 = head2.next;
}
while (head1 != null && head2 != null) {
if (head1.data < head2.data) {
current.next = head1; // 新链表中,current指针的下一个结点对应较小的那个数据
current = current.next; // current指针下移
head1 = head1.next;
} else {
current.next = head2;
current = current.next;
head2 = head2.next;
}
}
// 合并剩余的元素
if (head1 != null) { // 说明链表2遍历完了,是空的
current.next = head1;
}
if (head2 != null) { // 说明链表1遍历完了,是空的
current.next = head2;
}
return head;
}
2. Use recursão para alcançar
// 两个参数代表的是两个链表的头结点
public static Node merage(Node head1, Node head2) {
if (head1 == null)
return head2;
if (head2 == null)
return head1;
Node head3 = null;
if (head1.data < head2.data) {
head3 = head1;
head3.next = merage(head1.next, head2);
} else {
head3 = head2;
head3.next = merage(head1, head2.next);
}
return head3;//返回合并后链表的头结点
}
4. Determine se a lista vinculada tem um anel
Ideia: para definir dois ponteiros, usamos dois ponteiros para atravessar: o primeiro ponteiro se move um passo por vez, e o segundo ponteiro move dois passos por vez. Se o primeiro ponteiro e o segundo ponteiro se encontram, há um loop.
// 判断单链表是否有环,我们用两个指针去遍历:
// first指针每次走一步,second指针每次走两步,如果first指针和second指针相遇,说明有环。
public static boolean hasCycle(Node head) {
if (head == null) {
return false;
}
Node first = head;
Node second = head;
while (second != null) {
first = first.next; // first指针走一步
second = second.next.next; // second指针走两步
if (first == second) { // 一旦两个指针相遇,说明链表是有环的
return true;
}
}
return false;
}
5. Encontre o k-ésimo nó na parte inferior da lista vinculada
Ideia convencional: assumindo que toda a lista ligada tem n nós, então o k-ésimo nó da parte inferior é o n-k + 1 º nó do início, então podemos percorrer a lista ligada duas vezes e contar a lista pela primeira vez. número de nós, na segunda vez, podemos encontrar o k-ésimo nó da parte inferior. Mas o entrevistador geralmente só precisa percorrer a lista vinculada uma vez, o que requer outra solução.
Definimos dois ponteiros. O primeiro ponteiro começa no ponteiro principal da lista encadeada e vai k-1 passos para a frente, e o segundo ponteiro permanece parado: começando no k-ésimo passo, o segundo ponteiro também começa no ponteiro principal de a lista encadeada. Inicie o percurso. Uma vez que a distância entre os dois ponteiros é mantida em k-1, quando o primeiro ponteiro (indo para a frente) atinge o nó final da lista encadeada, o segundo ponteiro (indo para trás) é exatamente o kth da parte inferior. Nós ...
public static Node FindKthtoTail(Node head, int k) {
if (head == null || k == 0)
return null;
Node slow = head;
Node fast = head;
for (int i = 0; i < k - 1; i++)
fast = fast.next;
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
Tópicos relacionados:
1 Encontre o nó do meio da lista vinculada. Se o número total da lista vinculada for ímpar, retorne o nó do meio; se for um número par, retorne qualquer um dos dois nós do meio. Para resolver este problema, também podemos definir dois ponteiros. Ao mesmo tempo, a partir do nó principal da lista encadeada, um ponteiro move-se um passo de cada vez e o outro ponteiro move-se dois passos de cada vez. o ponteiro mais rápido atinge o final da lista vinculada, vá O ponteiro mais lento está bem no meio da lista vinculada.
2. Determine se uma lista encadeada está em loop, conforme mencionado acima.