2.5 有序表

来源:互联网 发布:100兆访客网络限速多少 编辑:程序博客网 时间:2024/06/17 04:44

简述

有序表(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;}