2.5 有序表

简述

有序表(ordered list)是指所有元素按照递增或者递减的方式组织的线性表。
一些数据结构教材中,没有单独将有序表列出来讲解,因为有序表实际上只是线性表的一种特殊形式,大多数操作与线性表无异,只是插入和删除需要维护其有序性。
大多数情况下,有序表只需要对普通线性表执行一次排序操作就可以得到。
有序表的重要操作之一是二路归并。前面提到过二路归并排序算法的分析,其中核心的操作就是二路归并。
归并算法只需要对两个源有序表 LA,LB 分别用指针 p,q 扫描,目标表 L 的下一个元素取 min{LA[p],LB[q]} 即可。对于边界处理,可以将 LA,LB 额外增加一个元素 + 作为哨兵(sentinal);实际上,更倾向作表空的判断。
至于有序表的有序性,通常可以用来设计与二分查找相关的算法。

单链表的二路归并

接着2.3节的链表类使用,增加merge()成员函数进行归并。与数组的归并较为类似,只不过边界条件判断,和指针移动,略有区别。
其中clear()是自行定义的清空链表的操作,只保留头结点,并将长度_length设置为0。可以参考析构函数去写,这里从略。
下面给出的是单链表的二路归并,算法的时间复杂度为 O(m+n) ,空间复杂度 O(1)

template<typename _Ty>
SinglyLList<_Ty> & SinglyLList<_Ty>::merge(SinglyLList & slist1, SinglyLList & slist2){
    //先清空原有表
    this->clear();
    SinglyLListNode * p1 = slist1._head->next;
    SinglyLListNode * p2 = slist2._head->next;
    SinglyLListNode * tail = this->_head;
    //维护计数器作为循环终止条件
    int count = 0;
    _length = slist1.length() + slist2.length();
    while(count < _length){
        //尾插法建表
        SinglyLListNode * newnode = new SinglyLListNode;
        if(p1 && p2){
            if(p1->data < p2->data){
                newnode->data = p1->data;
                p1 = p1->next;
            }else{
                newnode->data = p2->data;
                p2 = p2->next;
            }
        }else{
            if(p1){
                newnode->data = p1->data;
                p1 = p1->next;
            }else{
                newnode->data = p2->data;
                p2 = p2->next;
            }
        }
        tail->next = newnode;
        tail = newnode;
        count++;    //计数器自增
    }
    return *this;
}

你可能感兴趣的:(数据结构课程)