数据结构之链表面试题汇总(二)-有序单向链表的合并、单向链表反转
2017-11-02 21:16
811 查看
date: 2016-08-18 9:13:00
title: 数据结构之链表面试题汇总(二)-有序单向链表的合并、单向链表反转
categories: 数据结构
版权声明:本站采用开放的[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可
所有文章出现的代码,将会出现在我的github中,名字可以根据类全名来找,我在github中的文件夹也会加目录备注。
若两个链表本来有序,在合并的时候,可以参照一下归并排序的归并部分,原理一样。
先比较两条链表的节点,先把小的放进新链表,当其中一条链表到达最后一个节点的时候结束循环
在结束循环后判断那条链表为空,然后直接设置下一个节点为另外一个链表的节点即可,这样就可以把剩下的节点都连接上
图解:
测试代码: 第二个链表中的元素都比第一个链表的元素大
运行结果:
测试代码二:第二个链表中有与第一个链表相同的元素:
运行结果:
可以考虑用栈来存放链表中的元素,然后再通过弹栈来存入新链表中来实现该功能,但是这样做不高效
也可以考虑用数组存放链表中的元素,然后通过倒序获取数组中的元素来实现
在这里主要讨论使用递归实现单向链表的反转
首先判断节点是否为空,为空抛异常
接着得到当前节点的下一个节点
把当前节点的下一个节点设置成null
把下一个节点作为参数递归调用,返回的是最后一个节点
把下一个节点的下一个节点设置成当前节点,下一个节点为5 当前节点为4 结果为5.setNext(4)
还有4 3,3 2 ,2 1 完成之后返回递归返回的节点,即新链表的头节点
图解
代码实现:包含使用栈、双指针、递归的方法
测试代码:
运行结果:
title: 数据结构之链表面试题汇总(二)-有序单向链表的合并、单向链表反转
categories: 数据结构
版权声明:本站采用开放的[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可
所有文章出现的代码,将会出现在我的github中,名字可以根据类全名来找,我在github中的文件夹也会加目录备注。
合并两个有序的单向链表,合并之后的链表依然有序【出现频率高】(剑指offer,题17)
思路:若两个链表本来有序,在合并的时候,可以参照一下归并排序的归并部分,原理一样。
先比较两条链表的节点,先把小的放进新链表,当其中一条链表到达最后一个节点的时候结束循环
在结束循环后判断那条链表为空,然后直接设置下一个节点为另外一个链表的节点即可,这样就可以把剩下的节点都连接上
图解:
public class MergeList { public static Node mergeList(Node head1, Node head2) { // first judge 2 head is null together if (head1 == null && head2 == null) { throw new RuntimeException("the 2 of them are null"); } // judge if one of them is null then return another if (head1 == null) return head2; if (head2 == null) return head1; // declare two variables to record the newHead and current pointers Node newHead; Node current; // get the first in the new node if (head1.getRecord() < head2.getRecord()) { newHead = head1; current = head1; head1 = head1.getNext(); } else { newHead = head2; current = head2; head2 = head2.getNext(); } // loop that put the less one to the list and update the position while // one of them is null while (head1 != null && head2 != null) { if (head1.getRecord() < head2.getRecord()) { current.setNext(head1); current = current.getNext(); head1 = head1.getNext(); } else { current.setNext(head2); current = current.getNext(); head2 = head2.getNext(); } } // if one of them are null which indicates that the other is not null // and put if (head1 == null) { current.setNext(head2); } if (head2 == null) { current.setNext(head1); } // is to the list // return new list return newHead; } }
测试代码: 第二个链表中的元素都比第一个链表的元素大
public class ReverseLinkedListTest { public static void main(String[] args) { Node node1 = new Node(1); Node node2 = new Node(2); Node node3 = new Node(3); Node node4 = new Node(4); node1.setNext(node2); node2.setNext(node3); node3.setNext(node4); Node list1 = new Node(7); Node list2 = new Node(8); Node list3 = new Node(9); Node list4 = new Node(10); list1.setNext(list2); list2.setNext(list3); list3.setNext(list4); RecustionAllElementOfLinkedList.printAllElements(MergeList.mergeList( node1, list1)); } }
运行结果:
测试代码二:第二个链表中有与第一个链表相同的元素:
public class ReverseLinkedListTest { /** * @param args */ public static void main(String[] args) { Node node1 = new Node(1); Node node2 = new Node(2); Node node3 = new Node(3); Node node4 = new Node(4); node1.setNext(node2); node2.setNext(node3); node3.setNext(node4); Node list1 = new Node(1); Node list2 = new Node(2); Node list3 = new Node(6); Node list4 = new Node(7); list1.setNext(list2); list2.setNext(list3); list3.setNext(list4); RecustionAllElementOfLinkedList.printAllElements(MergeList.mergeList( node1, list1)); } }
运行结果:
单链表的反转【出现频率最高】(剑指offer,题16)
思路:可以考虑用栈来存放链表中的元素,然后再通过弹栈来存入新链表中来实现该功能,但是这样做不高效
也可以考虑用数组存放链表中的元素,然后通过倒序获取数组中的元素来实现
在这里主要讨论使用递归实现单向链表的反转
首先判断节点是否为空,为空抛异常
接着得到当前节点的下一个节点
把当前节点的下一个节点设置成null
把下一个节点作为参数递归调用,返回的是最后一个节点
把下一个节点的下一个节点设置成当前节点,下一个节点为5 当前节点为4 结果为5.setNext(4)
还有4 3,3 2 ,2 1 完成之后返回递归返回的节点,即新链表的头节点
图解
代码实现:包含使用栈、双指针、递归的方法
public class ReverseLinkedListUtil { /** * use stack to reverse single-direction LinkedList * * @param head * the head of a LinkedList * @return the new head of a LinkedList */ public static Node reverseByStack(Node head) { Stack<Node> nodes = new Stack<Node>(); if (head == null) { throw new RuntimeException("the Node is null !"); } // put all the node to the stack while (head != null) { nodes.push(head); head = head.next; } // get all the node in the stack head = nodes.pop(); Node curNode = head; while (!nodes.isEmpty()) { // update the next of the node Node nextNode = nodes.pop(); nextNode.setNext(null); curNode.setNext(nextNode); curNode = nextNode; } // return the new head return head; } /** * use 2 pointers to reverse the single-direction LinkedList * * @param head * the head of a single-direction LinkedList * @return the new head of a single-directionLinkedList */ public static Node reverseByPointer(Node head) { // define the previous node to record the previous node Node previous = null; // judge that the current node is null while (head != null) { // if true move the 2 pointers backward // get the next node and record it Node next = head.getNext(); // set the next.next to previous head.setNext(previous); // set the previous to current (head) previous = head; // set the next to next head = next; } // else break out the loop return previous; } /** * use recursion to reverse the single-direction LinkedList * * @param head * the head of the LinkedList * @return the new-head of the LinkedList that has been reversed */ public static Node reverseByRecur(Node head) { // if the tail is reached return it if (head == null || head.next == null) return head; // get the next node Node nextNode = head.getNext(); // set the current node's next node to null head.setNext(null); // recursion Node recursionResult = reverseByRecur(nextNode); // set the next node's next node to current nextNode.setNext(head); // return the value that was returned from the recursion return recursionResult; } }
测试代码:
public class ReverseLinkedListTest { /** * @param args */ public static void main(String[] args) { Node node1 = new Node(1); Node node2 = new Node(2); Node node3 = new Node(3); Node node4 = new Node(4); Node node5 = new Node(5); node1.setNext(node2); node2.setNext(node3); node3.setNext(node4); node4.setNext(node5); RecustionAllElementOfLinkedList.printAllElements(ReverseLinkedListUtil .reverseByRecur(node1)); } }
运行结果:
相关文章推荐
- 数据结构之链表面试题汇总(一)--查找单向链表的中间节点、倒数第K个节点
- 数据结构与算法之—链表(二) 有序单链表合并
- 数据结构与算法——有序链表合并
- 剑指offer面试题17,18:反转链表+合并有序链表
- 数据结构——单链表的创建、逆置、插入、有序表的建立、有序单链表合并等基础操作!!
- 数据结构与算法(二)合并两个有序链表
- 数据结构——算法之(033)(两个有序单链表合并为一个有序的单链表)
- 【学习点滴-数据结构-单链表】单链表的建立,遍历及有序单链表合并
- 数据结构基础 - 两个有序链表序列的合并
- 【数据结构作业二】写出单链表结点的结构体类型定义及查找、插入、删除算法,并以单链表作存储结构,实现有序表的合并
- 数据结构与算法 2、单向/双向链表
- c语言_数据结构_单向循环链表
- 数据结构之链表与数组(二) -单向链表上的简单操作问题
- [PTA] 线性结构1 两个有序链表序列的合并(15 分)
- 数据结构之单向链表
- 数据结构实验之链表六:有序链表的建立
- 剑指offer面试题15——扩展2:判断一个单向链表是否形成环结构
- SDUT 2119-数据结构实验之链表四:有序链表的归并
- 数据结构之有序链表归并算法2
- 数据结构实验之链表六:有序链表的建立