归并两个有序链表
1、题目描述
利用基础题里构建的单链表类创建两个有序的整数链表对象,实现将两个有序链表归并成一个新的有序链表并输出该新有序链表的结果。(可以调用已定义的链表类的方法来实现,并注意如何将两个有序的线性表进行归并的算法)
2、设计思路
首先通过InputRear()函数构造两个链表,通过不断修改last指针的指向。
- last->link = newNode;
- last = newNode;
只要用户没有输入标志结束的数据0,便一直将链表扩展下去。
最终令last->link = NULL;
链表的合并,整体思路与顺序表的合并相似,通过比较两个链表元素的大小,将小的元素赋值给新的链表,指针不断改变指向以循环整个链表
- r->link=p;
- r = p;
- p = p->link;
或者是
- r->link=q;
- r = q;
- q = q->link;
与线性表不同的是,链表中判断一个链表是否取遍可用p是否等于NULL来确定,当一个链表取遍后,将另一个链表剩下的结点连接到新链表即可。
头文件代码如下:
- #include<iostream>
- using namespace std;
- //#include"LinearList.h"
- template <class T> ?//结点结构定义
- struct LinkNode {
- ?? ?T data; ? ? ? ? ? ? ? ? ? ? ? ? //结点数据?
- ?? ?LinkNode<T>* link; ? ?//结点链接指针
- ?? ?LinkNode(LinkNode<T>* ptr = NULL) { link = ptr; } ?//构造函数?? ?
- ?? ?LinkNode(const T& item, LinkNode<T>* ptr = NULL) { data = item; link = ptr; }
- };
- template<class T>
- class List{
- protected:
- ?? ?struct LinkNode<T>* first;
- public:
- ?? ?List() { first = new LinkNode<T>; } ? ? ? ? //构造函数
- ?? ?List(const T& x) { first = new LinkNode<T>(x); } ? ? ?//构造函数
- ?? ?List(List<T>& L); ? ? ? ? ? ? //复制构造函数
- ?? ?~List() { makeEmpty(); } ? ? ? ? ? ?//析构函数
- ?? ?void makeEmpty(); ? ? ? ? ? ? //将链表置空
- ?? ?int Length() const; ? ? ? ? ? ? //计算链表的长度
- ?? ?LinkNode<T>* getHead() const { return first; }
- ?? ?LinkNode<T>* Search(T x); ? ? ? ? ? //搜素数据为x的节点
- ?? ?LinkNode<T>* Locate(int i)const; ? ? ? ? ?//搜索第i个元素的地址
- ?? ?bool getData(int i, T& x) const; ? ? ? ? //取出第i个节点的数据
- ?? ?void setData(int i, T& x); ? ? ? ? ? //用x修改第i个元素的值
- ?? ?bool Insert(int i, T& x); ? ? ? ? ? //在第i个节点后插入新节点
- ?? ?bool Remove(int i, T& x); ? ? ? ? ? //删除第i个节点数据返回到x中
- ?? ?bool IsEmpty() const ? ? ? ? ? ?//判断表是否为NULL
- ?? ?{
- ?? ??? ?return first->link == NULL ? true : false;
- ?? ?}
- ?? ?bool IsFull() const { return false; } ? ? ? ?//判断表满
- ?? ?void InputFront(T ?endFlag); ? ? ? ? ?//倒序创建单链表
- ?? ?void InputRear(T endFlag); ? ? ? ? ? //正序创建单链表
- ?? ?void Output(); ? ? ? ? ? ? ?//输出
- };
.cpp文件如下:
将两个有序链表合并为一个新的有序链表并返回
新链表是通过拼接给定的两个链表的所有节点组成的。
示例
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
- /**
- ?* Definition for singly-linked list.
- ?* struct ListNode {
- ?* ? ? int val;
- ?* ? ? ListNode *next;
- ?* ? ? ListNode(int x) : val(x), next(NULL) {}
- ?* };
- ?*/
- class Solution {
- public:
- ? ? ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
- ? ? ? ? ListNode* p = new ListNode(0);
- ? ? ? ? ListNode* temp = p;
- ? ? ? ? while( l1 || l2 ){
- ? ? ? ? ? ? if(l1==NULL){
- ? ? ? ? ? ? ? ? p->next = l2;
- ? ? ? ? ? ? ? ? break;
- ? ? ? ? ? ? }else if(l2==NULL){
- ? ? ? ? ? ? ? ? p->next = l1;
- ? ? ? ? ? ? ? ? break;
- ? ? ? ? ? ? }else{
- ? ? ? ? ? ? ? ? if ( l1->val < l2->val ){
- ? ? ? ? ? ? ? ? ? ? p->next = l1;
- ? ? ? ? ? ? ? ? ? ? l1 = l1->next;
- ? ? ? ? ? ? ? ? }else{
- ? ? ? ? ? ? ? ? ? ? p->next = l2;
- ? ? ? ? ? ? ? ? ? ? l2 = l2->next;
- ? ? ? ? ? ? ? ? }
- ? ? ? ? ? ? ? ? p=p->next;
- ? ? ? ? ? ? }
- ? ? ? ? }
- ? ? ? ? return temp->next;
- ? ? }
- };
因为经过while循环后,指针p的位置已经发生改变,所以需要一个辅助指针temp保存其初始位置。
因为在定义指针p的时候给它赋值了一个自定义的ListNode节点地址(相当于一个附加头指针),所以最后函数返回的应该是该结点的下一个结点,即temp->next。
在力扣上的提交结果
执行用时 : 16 ms, 在Merge Two Sorted Lists的C++提交中击败了95.72% 的用户
内存消耗 : 8.9 MB, 在Merge Two Sorted Lists的C++提交中击败了84.45% 的用户
以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。