zoukankan      html  css  js  c++  java
  • 问题:如何实现一个高效的单向链表逆序输出?

    需要考虑因素,高效应权衡多方面因素

    • 数据量是否会很大
    • 空间是否有限制
    • 原始链表的结构是否可以更改
    • 时间复杂度是否有限制
    • 一个链表节点需要输出的元素有多个,例如链表中存的是自定义对象,有多个字段

    1. 直接递归(简单,但O(n)空间复杂度不支持大数据量)

    // 直接递归实现核心代码片段
    public void reverse(head){
    	// 递归终止条件
    	if(head.next == null){
    		print(head);
    		return;
    	}
    	// 下一层需要做的事儿
    	reverse(head.next);
    	// 本层需要做的事儿
    	print(head);
    }
    

    2. 采用栈进行存储(O(n)时间复杂度,但不支持大数据量,栈中需要存储所有节点)

    // 采用栈进行存储实现核心代码片段
    public void reverse(head){
    	Node cur = head;
    	// 将所有元素入栈
    	while(cur != null){
    		stack.push(cur);
    		cur = cur.next;
    	}
    	// 将所有元素出栈
    	while(!stack.isEmpty){
    		print(stack.poll);
    	}
    }
    

    class Solution<T> {
    
        public void reverse(ListNode<T> head) {
           if (head == null || head.next == null) {
        	   return ;
           }
           ListNode<T> currentNode = head;
           Stack<ListNode<T>> stack = new Stack<>();
           while (currentNode != null) {
        	   stack.push(currentNode);
        	   ListNode<T> tempNode = currentNode.next;
        	   currentNode.next = null; // 断开连接
        	   currentNode = tempNode;
           }
           
           head = stack.pop();
           currentNode = head;
           
           while (!stack.isEmpty()) {
        	   currentNode.next = stack.pop();
        	   currentNode = currentNode.next;
           }
        }
    }
    
    class ListNode<T>{
    	T val;
    	public ListNode(T val) {
    		this.val = val;
    	}
    	ListNode<T> next;
    }

    3. 直接遍历(不需要额外存储空间,但O(n^{^{2})时间复杂度)

    // 直接遍历实现核心代码
    public void reverse(head){
    	Node cur = head;
    	int count = 0;
    	// 统计链表节点个数
    	while(cur != null){
    		count ++;
    		cur = cur.next;
    	}
    	// 每次从前往后进行扫描输出
    	for(int i = count; i > 0; i--){
    		int tmp = i;
    		cur = head;
    		while(tmp-- != 0){
    			cur = cur.next;
    		}
    		print(cur)
    	}
    }
    

    4. 翻转链表再遍历(O(n)时间复杂度且不需要额外存储空间,但需要改变原始链表结构)

    // 翻转链表实现核心代码
    public void reverse(head){
        Node cur = head.next;
        Node pre = head;
        pre.next = null;
        Node tmp = new Node();
        // 翻转链表
        while(cur != null){
            tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        // 输出
        while(pre != null){
            print(pre);
            pre = pre.next;
        }
        
    }

    typedef struct node{
        int           data;
        struct node*  next;
        node(int d):data(d), next(NULL){}
    }node;
    
    void reverse(node* head)
    {
        if(head == NULL){
            return;
        }
    
        node* pleft = NULL;
        node* pcurrent = head;
        node* pright = head->next;
    
        while(pright){
            pcurrent->next = pleft;
            node *ptemp = pright->next;
            pright->next = pcurrent;
            pleft = pcurrent;
            pcurrent = pright;
            pright = ptemp;
        }
    
        while(pcurrent != NULL){
            cout<< pcurrent->data << "	";
            pcurrent = pcurrent->next;
        }
    }
    


    5. 头插法新建空链表(简单,但是O(n)空间复杂度)

    // 头插法新建空链表实现核心代码
    public void reverse(head){
        Node result = copy(head);
        Node cur = head;
        cur = cur.next;
        // 新建链表节点,头插法构建
        while(cur != null){
            Node tmp = copy(cur.next);
            tmp.next = pre;
            pre = tmp;
            cur = cur.next;
        }
    }
     


    参考链接:

    https://blog.csdn.net/Kaiyang_Shao/article/details/89527906

    https://github.com/debitCrossBlockchain/interview__reference/blob/master/01.%E9%98%BF%E9%87%8C%E7%AF%87/1.1.1%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84%E5%8D%95%E5%90%91%E9%93%BE%E8%A1%A8%E9%80%86%E5%BA%8F%E8%BE%93%E5%87%BA%EF%BC%9F.md

  • 相关阅读:
    CR, LF, CR/LF区别与关系
    利用 jQuery 克隆 Object
    【2015】网易前端面经
    前端架构:Angular与requirejs集成实践
    高质量代码之HTML、CSS篇
    【转】requirejs简单入门
    2014搜狗前端面经【B事业部】
    2014小型公司前端面经
    【转】对象创建模式
    2014搜狗前端面经【A事业部】
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13312576.html
Copyright © 2011-2022 走看看