Resumo das questões do teste de superfície da cadeia (implementação java)

 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.


Crie uma pilha você mesmo
//方法:从尾到头打印单链表
	     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.




Acho que você gosta

Origin blog.csdn.net/a447332241/article/details/78997019
Recomendado
Clasificación