合并k个排序链表,力扣上原题,有一些问题

class Solution {
public:
ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
if ((!a) || (!b)) return a ? a : b;
ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
while (aPtr && bPtr) {
if (aPtr->val < bPtr->val) {
tail->next = aPtr; aPtr = aPtr->next;
} else {
tail->next = bPtr; bPtr = bPtr->next;
}
tail = tail->next;
}
tail->next = (aPtr ? aPtr : bPtr);
return head.next;
}

ListNode* merge(vector <ListNode*> &lists, int l, int r) {
    if (l == r) return lists[l];
    if (l > r) return nullptr;
    int mid = (l + r) >> 1;
    return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}

ListNode* mergeKLists(vector<ListNode*>& lists) {
    return merge(lists, 0, lists.size() - 1);
}

};
这是力扣的原题官方解答,分治合并,我有几个问题,来个认真负责任的大佬
问:if ((!a) || (!b)) return a ? a : b;这段代码有什么意义呢,为什么不写成if ((a) || (b))
问:tail->next = (aPtr ? aPtr : bPtr);这段代码的优先级是什么,为什么不写成(tail->next = aPtr) ? aPtr : bPtr;
问:int mid = (l + r) >> 1;这段代码什么意思,为什么不去写成int mid = (l + r) /2,希望能讲详细一点
问: ListNode head, *tail = &head,我为什么不能写成 ListNode &head, tail = head
问:ListNode
mergeTwoLists(ListNode *a, ListNode b)为什么不能写成ListNode mergeTwoLists(ListNode a, ListNode b)

来个负责任的大佬

问:if ((!a) || (!b)) return a ? a : b;这段代码有什么意义呢,为什么不写成if ((a) || (b))
这个是如果合并两个链表中有一个指针为空,就没必要执行了,返回不为空的;如果都是空的,返回NULL。
写成if ((a) || (b)) 与 if ((!a) || (!b)) 逻辑就不一样了。

问:tail->next = (aPtr ? aPtr : bPtr);这段代码的优先级是什么,为什么不写成(tail->next = aPtr) ? aPtr : bPtr;
给tail->next赋值,将剩余的未合并的链表添加到末尾。(aPtr ? aPtr : bPtr) : aPtr不为空,就是剩余aPtr;否则就是bPtr;
写成(tail->next = aPtr) ? aPtr : bPtr; 是什么作用呢?

问:int mid = (l + r) >> 1;这段代码什么意思,为什么不去写成int mid = (l + r) /2,希望能讲详细一点
效果是一样的,右移的执行效率高一点

问: ListNode head, *tail = &head,我为什么不能写成 ListNode &head, tail = head
定义head以及tail指针。
写成ListNode &head, tail = head; 这是定义引用而且没有赋值,再定义tail变量? 那想这么写是想表达什么呢?

问:ListNode* mergeTwoLists(ListNode *a, ListNode *b)为什么不能写成ListNode mergeTwoLists(ListNode a, ListNode b)
这里链表采用指针结构,修改指针的指向对象,从而达到合并效果。如果写成ListNode方式,那就势必要从指针转换为变量,增加无谓的转换,还有可能出错。

关于你的疑问见代码注释

class Solution
{
public:
    ListNode *mergeTwoLists(ListNode *a, ListNode *b)
    {
        if ((!a) || (!b)) return a ? a : b; // 这句用来处理a或b是nullptr的情况,因为merge()函数中当l > r时返回nullptr
        ListNode head, *tail = &head, *aPtr = a, *bPtr = b; // 这个语句相当于下面这些语句
                                                            // ListNode head;
                                                            // ListNode *tail = &head;
                                                            // ListNode *aPtr = a;
                                                            // ListNode *bPtr = b;
        while (aPtr && bPtr)
        {
            if (aPtr->val < bPtr->val)
            {
                tail->next = aPtr;
                aPtr = aPtr->next;
            }
            else
            {
                tail->next = bPtr;
                bPtr = bPtr->next;
            }
            tail = tail->next;
        }
        tail->next = (aPtr ? aPtr : bPtr); // 三目运算符?:和赋值运算符=具有相同的优先级,结合律是从右向左,
                                           // 所以这里的括号是可以省略的,不过加上括号可以提高代码的阅读性。
                                           // 这句代码相当于
                                           // if (aPtr)
                                           //     tail->next = aPtr;
                                           // else
                                           //     tail->next = bPtr;
        return head.next;
    }

    ListNode *merge(vector<ListNode *> &lists, int l, int r)
    {
        if (l == r)
            return lists[l];
        if (l > r)
            return nullptr;
        int mid = (l + r) >> 1;  // 相当于 mid = (l + r) / 2,一般来说位移操作比算术运算快
        return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
    }

    ListNode *mergeKLists(vector<ListNode *> &lists)
    {
        return merge(lists, 0, lists.size() - 1);
    }
};