C++进阶与拔高(二)(C++数据结构的具体实现:向量与列表)

注意:本章节《C++数据结构具体实现》均转载自博客:https://blog.csdn.net/qq_23912545/article/category/6868003

第一章 C++数据结构的具体实现

本章节的所有代码均是博主前面几篇博客的参考,C++及数据结构复习笔记(十一~十二)的参考,可以说是前面所讲数据结构时,对所有模板类以及ADT接口的一个整合。可以辅助大家对于数据结构具体实现的理解。其中有很大一部分是我在前面的博客中没有讲到的,读者可以根据自己的情况决定是否精进。

1.1 向量Vector的具体实现

#ifndef VECTOR_H
#define VECTOR_H
#include "Fib.h"
typedef int Rank;//秩
#define DEFAULT_CAPACITY 3 //默认的初始容量
template <typename T> class Vector{ //向量模板类
protected: 
    Rank _size; int _capacity; T* _elem;//规模、容量、数据区
    void copyFrom(T const *A, Rank lo, Rank hi);//复制数组区间A[lo,hi)
    void expand();//空间不足时扩容
    void shrink();//装填因子过小时压缩
    Rank bubble(Rank lo, Rank hi);//扫描交换
    void bubbleSort(Rank lo, Rank hi);//起泡排序算法
    Rank max(Rank lo, Rank hi);//选取最大元素
    void selectionSort(Rank lo, Rank hi);//选择排序算法
    void merge(Rank lo, Rank mi, Rank hi);//归并算法
    void mergeSort(Rank lo, Rank hi);//归并排序算法
    Rank partition(Rank lo, Rank hi);//轴点构造算法
    void quickSort(Rank lo, Rank hi);//快速排序算法
    void heapSort(Rank lo, Rank hi);//堆排序
public:
    //构造函数
    Vector(int c = DEFAULT_CAPACITY,int s = 0 ,T v = 0){ //容量为c,规模为s,所有元素初始化v
        _elem = new T[_capacity = c];
        for (_size = 0; _size < s; _elem[_size++] = v);//s<=c
    }
    Vector(T const *A, Rank n){//数组整体复制
        copyFrom(A, 0, n);
    }
    Vector(T const *A, Rank lo, Rank hi){//数组区间
        copyFrom(A, lo, hi);
    }
    Vector(Vector<T> const& V, Rank lo, Rank hi){//向量区间
        copyFrom(V._elem, lo, hi);
    }
    Vector(Vector<T> const& V){//向量整体复制
        copyFrom(V._elem, 0, v._size);
    }
    //析构函数
    ~Vector(){
        delete[] _elem;//释放空间
    }
    //只读访问接口
    Rank size() const{ return _size; }//规模
    bool empty() const{ return !_size; }//判空
    int disordered() const;//判断向量是否已排序
    Rank find(T const& e) const { return find(e, 0, _size); }//无序向量整体查找
    Rank find(T const &e, Rank lo, Rank hi) const;//无序向量区间查找
    Rank search(T const& e) const{//有序向量整体查找
        return(0 >= _size) ? -1 : search(e, 0, _size);
    }
    Rank search(T const& e, Rank lo, Rank hi) const;//有序向量区间查找

    //可写访问接口
    T& operator[] (Rank r) const;//重载下标操作符
    Vector<T> & operator= (Vector<T> const&); //重载赋值操作符以便于克隆向量
    T remove(Rank r);//删除秩为r的元素
    int remove(Rank lo, Rank hi);//删除秩在区间[lo,hi)之内的元素
    Rank insert(Rank r, T const& e);//插入元素
    Rank insert(T const& e){ return insert(_size, e); }//默认作为末元素插入
    void sort(Rank lo, Rank hi);//对[lo,hi)排序
    void sort(){ sort(0, _size); }//整体排序
    void unsort(Rank lo, Rank hi);//对[lo,hi)置乱
    void unsort(){ unsort(0, _size); }//整体置乱
    int deduplicate();//无序去重
    int uniquify();//有序去重
    //遍历
    void traverse(void(*visit)(T&));//遍历(使用函数指针,只读或者局部性修改)
    template <typename VST> void traverse(VST&);//遍历(使用函数对象,可全局性修改)
};
//函数定义
template <class T>
void Vector<T>::copyFrom(T const *A, Rank lo, Rank hi){
    _elem = new T[_capacity = 2 * (hi - lo)];//分配空间
    _size = 0;//规模清零
    while (lo < hi)//[lo,hi)内的元素逐一
        _elem[_size++] = A[lo++];//复制到_elem[0,hi-lo)
}
template <class T>
void Vector<T>::expand(){
    if (_size < _capacity) return;//尚未满员,不必扩容
    if (_capacity < DEFAULT_CAPACITY)_capacity = DEFAULT_CAPACITY;//不低于最小容量
    T* oldElem = _elem;
    _elem = new T[_capacity <<= 1];//容量倍增
    for (int i = 0; i < _size; i++)
        _elem[i] = oldElem[i];//T为基本类型,或者已经重载复制操作符"="
    delete[] oldElem;//释放原空间
}
template<class T>
Rank Vector<T>::insert(Rank r, T const& e){//插入操作
    expand();//若有必要扩容
    for (int i = _size; i > r; i--)//自后向前
        _elem[i] = _elem[i - 1];
    _elem[r] = e; _size++; return r;//置入新元素,更新容量,返回秩
}
template<class T>
void Vector<T>::traverse(void(*visit)(T &)){//利用函数指针机制,只读或者局部性修改
    for (int i = 0; i < _size; i++)
        visit(_elem[i]);//遍历向量
}
template<typename T> template<typename VST>
void Vector<T>::traverse(VST& visit){//借助函数对象机制
    for (int i = 0; i < _size; i++)
        visit(_elem[i]);//遍历向量
}
template<typename T>
int Vector<T>::disordered() const{
    int n = 0;
    for (int i = 1; i < _size; i++)
        n += (_elem[i - 1]>_elem[i]);//逆序则计数
    return n;//向量有序当且仅当n=0
}
template<class T>
T& Vector<T>::operator[](Rank r) const{//重载下标操作符
    return _elem[r]; //0 <= r < _size
}
template<class T>
int Vector<T>::remove(Rank lo, Rank hi){//区间删除[lo,hi)
    if (lo == hi) return 0;//单独处理退化情况
    while (hi < _size) _elem[lo++] = _elem[hi++];//[hi, _size)顺次前移
    _size = lo; shrink();//更新规模,若有必要则缩容
    return hi - lo;//返回被删除元素的数目
}
template<class T>
T Vector<T>::remove(Rank r){//单元素删除,可作为区间删除的特例
    T e = _elem[r];//备份删除的元素
    remove(r, r + 1);//调用区间删除算法
    return e;//返回被删除的元素
}
template<class T>
void Vector<T>::shrink(){
    if (_capacity < DEFAULT_CAPACITY << 1)return;//不至于收缩到DEFAULT_CAPACITY以下
    if (_size << 2>_capacity)return;//已25%为界
    T* oldElem = _elem; _elem = new T[_capacity >>= 1];//容量减半
    for (int i = 0; i < _size; i++) _elem[i] = oldElem[i];//复制原内容
    delete[] oldElem;//释放原空间
}
template<class T>
Rank Vector<T>::find(T const & e, Rank lo, Rank hi) const{//无序向量的顺序查找:返回最后一个元素e的位置;失败时,返回lo-1
    while ((lo < hi--) && (e != _elem[hi]));//从后顺序查找
    return hi;//若hi<lo,则意味着失败,否则即为命中元素
}
template<class T>
int Vector<T>::deduplicate(){//无序向量去重操作
    int oldSize = _size;//记录原规模
    Rank i = 1;
    while (i < _size)
        (find(_elem[i], 0, i) < 0) ?
        i++ ://若无雷同则继续向后考察
        remove(i);//否则删除重复元素
    return oldSize - _size;//返回规模变化量 即被删除元素的个数
}
template<typename T>
int Vector<T>::uniquify(){//有序向量重复去重算法(高效版)
    Rank i = 0, j = 0;//各对互异元素的秩
    while (++j<_size)
    if (_elem[i] != _elem[j])
        _elem[++i] = _elem[j];//发现不同时向前移动至前者的紧邻右侧
    _size = ++i; shrink();//直接劫除尾部多余元素
    return j - i;//向量规模变化量,即被删除元素的个数
}
template<typename T>
void Vector<T>::sort(Rank lo, Rank hi){//向量区间[lo,hi)排序
    switch (rand()%5){//随机选取排序算法。可根据具体问题的特点灵活选取或者扩充
    case 1:bubbleSort(lo, hi); break;//起泡排序
    case 2:selectionSort(lo, hi); break;//选择排序
    case 3:mergeSort(lo, hi); break;//归并排序
    case 4:heapSort(lo, hi); break;//堆排序
    default:quickSort(lo, hi);//快速排序
    }
}
template<typename T>
Rank Vector<T>::search(T const& e, Rank lo, Rank hi) const{//在有序向量的区间[lo,hi)内,确定不大于e的最后一个节点的秩
    return(rand() % 2) ? binSearch(_elem, e, lo, hi) : fibSearch(_elem, e, lo, hi);//各按照50%随机使用二分查找和fibonacci查找
}
template<typename T>
void Vector<T>::bubbleSort(Rank lo, Rank hi){//向量的起泡排序
    while (lo < (hi = bubble(lo, hi)));//逐趟做扫描交换直至全序
}
template<typename T>
Rank Vector<T>::bubble(Rank lo, Rank hi){//一趟扫描交换
    Rank last = lo;//最右侧的逆序对初始化为[lo-1,lo]
    while (++lo<hi)//自左向右,逐一检查各对相邻元素
    if (_elem[lo - 1]>_elem[lo]){
        last = lo;//更新最右侧逆序对位置记录,并
        swap(_elem[lo - 1], _elem[lo]);//通过交换使局部有序
    }
    return last;//返回最右侧的逆序对位置
}
/*
template<typename T>
void swap(T const& A, T const& B){//交换两个T类型元素
    T C = B;
    B = A; A = C;
}
*/
template<typename T>
void Vector<T>::mergeSort(Rank lo, Rank hi){
    if (hi - lo < 2) return;//单元素区间自然有序,否则。。。
    int mi = (lo + hi) / 2;//以中点为界
    mergeSort(lo, mi);//分别排序
    mergeSort(mi, hi);
    merge(lo, mi, hi);//归并
}
template<typename T>//有序向量的归并
void Vector<T>::merge(Rank lo, Rank mi, Rank hi){//各自有序子向量[lo,mi) 和[mi,hi)
    T* A = _elem + lo;//合并后的向量A[0,hi - lo) = _elem[lo,hi)
    int lb = mi - lo; T*B = new T[lb];//前子向量B[0,1b)= _elem[lo,mi)
    for (Rank i = 0; i < lb; i++)B[i] = A[i];//复制前子向量
    int lc = hi - mi; T* C = _elem + mi;//后子向量C[0,1c) = _elem[mi,hi)
    for (Rank i = 0, j = 0, k = 0; (j < lb) || (k < lc);){//B[j] 和 C[k]中的小者续至A末尾
        if ((j < lb) && (!(k < lc) || (B[j] <= C[k]))) A[i++] = B[j++];
        if ((k < lc) && (!(j < lb) || (C[k] <= B[j]))) A[i++] = C[k++];
    }
    delete[] B;//释放临时空间B
}//归并后得到完整的有序向量[lo,hi)

//模板方法
//Fibonacci查找算法(版本A)
template <class T>
static Rank fibSearch(T* A, T const & e, Rank lo, Rank hi){
    Fib fib(hi - lo);//用O(log_phi(n = hi - lo)时间创建Fib数列
    while (lo < hi){//每次迭代可能要做两次比较判断,有三个分支
        while (hi - lo < fib.get()) fib.prev();//通过向前顺序查找 至多迭代几次?
        Rank mi = lo + fib.get() - 1;//确定形如Fib(k) -1 的轴点
        if (e < A[mi]) hi = mi;//深入前半段[lo,mi)继续查找
        else if (A[mi] < e) lo = mi + 1;//深入后半段(mi,hi)继续查找
        else return mi;//在mi处命中
    }//成功查找可以提前终止
    return -1;//查找失败
}//有多个命中的元素时,不能保证返回秩最大者,失败时简单返回-1,不能确定失败的位置
//
/*
//二分查找算法(版本A):在有序向量的区间[lo, hi)内查找元素e
template <typename T>
static Rank binSearch(T* A, T const & e, Rank lo, Rank hi){
    while (lo < hi){//每次迭代可能要做两次比较判断,有三个分支
        Rank mi = (lo + hi) >> 1;//以中点为轴点
        if (e < A[mi])hi = mi;//深入前半段[lo,mi)继续查找
        else if (A[mi] < e) lo = mi + 1;//深入后半段(mi,hi)继续查找
        else return mi;//在mi处命中
    }//成功查找提前终止
    return -1;//查找失败
}//有多个命中的元素时,不能保证返回秩最大者,失败时简单返回-1,不能确定失败的位置
//二分查找算法(版本B)
template<typename T> 
static Rank binSearch(T*A, T const& e, Rank lo, Rank hi){
    while (1 < hi - lo){//每步迭代仅需做一次比较判断,有两个分支;成功查找不能提前终止
        Rank mi = (lo + hi) >> 1;//以中点为轴点
        (e < A[mi]) ? hi = mi : lo = mi;//经比较后确定深入[lo,mi)或者[mi,hi)
    }//出口时hi= lo +1,查找区间仅含有一个元素A[lo]
    return(e == A[lo]) ? lo : -1;//查找成功时返回对应的秩,否则返回-1
}//有多个命中的元素时,不能保证返回秩最大者,失败时简单返回-1,不能确定失败的位置
*/
//
//二分查找算法(版本C)
template<typename T>
static Rank binSearch(T* A, T const& e, Rank lo, Rank hi){
    while (lo < hi){//每步迭代仅需做一次比较判断,有两个分支;成功查找不能提前终止
        Rank mi = (lo + hi) >> 1;//以中点为轴点
        (e < A[mi]) ? hi = mi : lo = mi + 1;//经过比较后确定[lo,mi)或(mi,hi)查找
    }
    return --lo;//循环结束时,lo为大于e的元素的最小秩,故lo-1为不大于e的元素的最大秩
}//有多个命中元素时,总能保证返回秩最大者;查找失败时,能够返回失败的位置
#endif // !VECTOR_H

1.2 列表List的具体实现

1.2.1 节点的实现

#ifndef LISTNODE_H
#define LISTNODE_H
typedef int Rank;//秩
#define ListNodePosi(T) ListNode<T>* //列表节点位置
template <typename T> struct ListNode{//列表节点模板类(以双向链表形式实现)
    //成员
    T data; ListNodePosi(T) pred; ListNodePosi(T) succ;
    //构造函数
    ListNode(){}//针对header 和trailer的构造
    ListNode(T e, ListNodePosi(T) p = NULL, ListNodePosi(T) s = NULL) :
        data(e), pred(p), succ(s){}//默认构造器
    //操作接口
    ListNodePosi(T) insertAsPred(T const& e);//紧靠当前节点之前插入新节点
    ListNodePosi(T) insertAsSucc(T const& e);//紧靠当前节点之后插入新节点
};
//类函数定义
template <typename T>//将e紧靠当前节点之前插入于当前节点所属列表(设有哨兵头节点header)
ListNodePosi(T) ListNode<T>::insertAsPred(T const& e){
    ListNodePosi(T) x = new ListNode(e, pred, this);//创建新节点
    pred->succ = x; pred = x;//设置正向链接
    return x;//返回新节点的位置
}
template <typename T>//将e紧靠当前节点之后插入于当前节点所属列表(设有哨兵头节点trailer)
ListNodePosi(T) ListNode<T>::insertAsSucc(T const& e){
    ListNodePosi(T) x = new ListNode(e, this, succ);//创建新节点
    succ->pred = x; succ = x;//设置反向链接
    return x;//返回新节点的位置
}
#endif // !LISTNODE_H

1.2.2 列表的实现

#ifndef LIST_H
#define LIST_H
#include "listNode.h"
template<typename T> class List{//列表模板类 
private:
    int _size; ListNodePosi(T) header; ListNodePosi(T) trailer;//规模、头尾哨兵
protected:
    void init();//初始化
    int clear();//清楚所有节点至表空
    void copyNodes(ListNodePosi(T), int);//复制列表中自p起的n项
    void merge(ListNodePosi(T)&, int, List<T>&, ListNodePosi(T), int);//归并
    void mergeSort(ListNodePosi(T)&, int);//归并排序
    void selectionSort(ListNodePosi(T), int);//选择排序
    void insertionSort(ListNodePosi(T), int);//插入排序
public:
    //构造函数
    List(){ init(); }
    List(List<T> const& L);
    List(List<T> const& L, Rank r, int n);//复制列表L中自第r项起的n项
    List(ListNodePosi(T) p, int n);//复制列表中自P位置起的n个节点
    //析构函数
    ~List();//释放所有节点
    //只读访问接口
    Rank size()const{ return _size; };//规模
    bool empty()const { return _size <= 0 };//判空
    ListNodePosi(T) operator[] (Rank r)const;//重载 支持循秩访问
    ListNodePosi(T) first()const{ return header->succ; }//首节点位置
    ListNodePosi(T) last()const{ return trailer->pred; }//末节点位置
    bool valid(ListNodePosi(T) p){//判断p位置对外是否合法
        return p && (trailer != p) && (header != p);
    }
    int disordered() const;//是否已经有序
    ListNodePosi(T) find(T const& e) const{//无序列表查找
        return find(e, _size, trailer);
    }
    ListNodePosi(T) find(T const& e, int n, ListNodePosi(T) p)const;//无序区间查找
    ListNodePosi(T) search(T const& e) const{//有序列表查找
        return search(e, _size, trailer);
    }
    ListNodePosi(T) search(T const& e, int n, ListNodePosi(T) p)const;//有序区间查找
    ListNodePosi(T) selectMax(ListNodePosi(T), int n);//在p及其n-1各后继中选出最大者
    ListNodePosi(T) selectMax(){ return selectMax(header->succ, _size); }//整体最大者

    //可写访问接口
    ListNodePosi(T) insertAsFirst(T const & e);//将e作为首节点插入
    ListNodePosi(T) insertAsLast(T const& e);//将e作为末节点插入
    ListNodePosi(T) insertA(ListNodePosi(T) p, T const& e);//将e作为p的后继插入(after)
    ListNodePosi(T) insertB(ListNodePosi(T) p, T const& e);//将e作为p的前驱插入(before)
    T remove(ListNodePosi(T) p);//删除合法位置p处的节点,返回被删除节点
    void merge(List<T>& L){ merge(first(), size, L, L.first, L._size); }//全列表归并
    void sort(ListNodePosi(T) p, int n);//列表区间排序
    void sort(){ sort(first(), _size); }//整体排序
    int deduplicate();//无序去重
    int uniquify();//有序去重
    void reverse();//前后倒置
    void traverse(void(*)(T&));//遍历,visit操作 (函数指针)
    template<typename VST> void traverse(VST&);//遍历,依次实施visit操作(函数对象)
};//List
//类函数的定义
//初始化
template <typename T>
void List<T>::init(){
    header = new ListNode<T>();
    trailer = new ListNode<T>();
    header->succ = trailer;
    trailer->pred = trailer;
    _size = 0;
}
//无序表的查找
template <typename T>
ListNodePosi(T) List<T>::find(T const& e, int n, ListNodePosi(T) p) const{
    while (0 < n--){//对于p的n个最近的真前驱,从右向左
        if (e == (p = p->pred)->data) return p;//逐个比对,直至命中或越界
    }
    return NULL;//p越界意味着失败
}//失败时返回NULL
//作为首节点插入
template <typename T> 
ListNodePosi(T) List<T>::insertAsFirst(T const& e){
    _size++; return header->insertAsSucc(e);//e当做首节点插入
}
//作为末节点插入
template <typename T>
ListNodePosi(T) List<T>::insertAsLast(T const& e){
    _size++; return trailer->insertAsPred(e);//e当做末节点插入
}
//作为当前节点的后继插入
template <typename T>
ListNodePosi(T) List<T>::insertA(ListNodePosi(T) p, T const& e){
    _size++; return p->insertAsSucc(e);//e当做p的后继插入
}
//作为当前节点的前驱插入
template <typename T>
ListNodePosi(T) List<T>::insertB(ListNodePosi(T) p, T const& e){
    _size++; return p->insertAsPred(e);//e当做p的前继插入
}
//基本接口
template <typename T>
void List<T>::copyNodes(ListNodePosi(T) p, int n){
    init();//创建头、尾节点并做初始化
    while (n--){//将起自p的n项依次作为末节点插入
        insertAsLast(p->data); p = p->succ;
    }
}
//重载下标操作符,以通过秩直接访问列表节点(虽方便,效率低,需慎用)
template <typename T>
ListNodePosi(T) List<T>::operator[] (Rank r) const{
    ListNodePosi(T) p = first();//从首节点出发
    while (0 < r--)p = p->succ;//顺数第r个节点即是
    return p;//目标节点,返回其中所存元素
}
//重载构造函数
template <typename T>
List<T>::List(List<T> const & L){
    copyNodes(L.first(), L._size);
}
template <typename T>
List<T>::List(List<T> const & L, int r, int n){
    copyNodes(L[r], n);
}
//删除合法节点p,返回其数值
template <typename T>
T List<T>::remove(ListNodePosi(T) p){
    T e = p->data;//备份待删除节点的数值(假定T类型可直接赋值)
    p->pred->succ = p->succ; p->succ->pred = p->pred;//后继、前驱
    delete p; _size--;//释放节点,更新规模
    return e;//返回备份的数值
}
//析构函数
template <typename T>
List<T>::~List(){
    clear(); delete header; delete trailer;
}
//清空列表
template <typename T>
int List<T>::clear(){
    int oldSize = _size;
    while (0 < _size)//反复删除首节点,直至表为空
        remove(header->succ);
    return oldSize;
}
//剔除无序列表中的重复节点
template <typename T>
int List<T>::deduplicate(){
    if (_size < 2)return 0;//平凡列表自然无重复
    int oldSize = _size;//记录原始规模
    ListNodePosi(T) p = header; Rank r = 0;//p从首节点开始
    while (trailer != (p = p->succ)){//依次直到末节点
        ListNodePosi(T) q = find(p->data, r, p);//在p的r个真前驱中查找雷同者
        q ? remove(q) : r++;//若的确存在,则删除之,否则秩加一
    }//assert:循环过程中的任意时刻p的所有前驱互不相同
    return oldSize - _size;//列表规模变化量,即被删除元素的总数
}
//借助函数指针机制遍历
template <typename T>
void List<T>::traverse(void(*visit)(T&)){
    for (ListNodePosi(T) p = header->succ; p != trailer; p = p->succ)
        visit(p->data);
}
//操作器 借助函数对象机制遍历
template <typename T> 
template<typename VST>
void List<T>::traverse(VST& visit){
    for (ListNodePosi(T) p = header->succ; p != trailer; p = p->succ)
        visit(p->data);
}
//有序列表去重
template <typename T> 
int List<T>::uniquify(){
    if (_size < 2)return 0;
    int oldSize = _size;
    ListNodePosi(T) p = first();
    ListNodePosi(T) q;
    while (trailer != (q = p->succ)){
        if (p->data != q->data) p = q;
        else remove(q);
    }
    return oldSize - _size;
}//只需要遍历整个列表一趟,O(n)
//在有序表内p节点的n个真前驱中找到不大于e的最后者
template <typename T>
ListNodePosi(T) List<T>::search(T const&e, int n, ListNodePosi(T) p)const{
    //assert:0<=n<=Rank(p)<_size
    do{
        p = p->pred; n--;
    } while ((-1 < n) && (e < p->data));//逐个比较直到命中或者越界
    return p;
}//失败时,返回区间左边界的前驱(可能是header)
//列表的选择排序算法:对起始于位置p的n个元素排序
template<typename T>
void List<T>::selectionSort(ListNodePosi(T) p, int n){
    ListNodePosi(T) head = p->pred; ListNodePosi(T) tail = p;
    for (int i = 0; i < n; i++)tail = tail->succ;//待排序区间(head,tail)
    while (1 < n){
        ListNodePosi(T) max = selectMax(head->succ, n);
        insertB(tail, remove(max));
        tail = tail->pred;
        n--;
    }
}
//从起始位置p的n个元素中选出最大者
template<typename T>
ListNodePosi(T) List<T>::selectMax(ListNodePosi(T) p, int n){
    ListNodePosi(T) max = p;
    for (ListNodePosi(T) cur = p; 1 < n; n--){
        if (!lt((cur = cur->succ)->data, max->data))
            max = cur;
    }
    return max;
}
//a小于b?
template<typename T>
bool lt(T a, T b){
    return a < b;
}
//列表的插入排序算法:对起始于位置p的n个元素排序
template<typename T>
void List<T>::insertionSort(ListNodePosi(T) p, int n){
    for (int r = 0; r < n; r++){
        insertA(search(p->data, r, p), p->data);
        p = p->succ; remove(p->pred);
    }
}
//有序列表的归并:当前列表中自p起的n个元素,与列表L中自q起的m个元素归并
template <typename T>
void List<T>::merge(ListNodePosi(T) & p, int n, List<T>&L, ListNodePosi(T) q, int m){
    ListNodePosi(T) pp = p->pred;//借助前驱,以便返回前。。。
    while (0 < m){//在q尚未移出区间之前
        if ((0 < n) && (p->data <= q->data)){//若p仍在区间内且v(p)<=v(q),则
            if (q == (p = p->succ))//p归入合并的列表,并替换为其直接后继
                break;
            n--;
        }
        else{//若p已经超出了右界或者v(q)<v(p),则
            insertB(p, L.remove((q = q->succ)->pred));//将q转移至p之前
            m--;
        }
    }
    p = pp->succ;//确定归并后区间的(新)起点
}
//列表的归并排序算法:对于起始于位置p的n个元素排序
template<typename T>
void List<T>::mergeSort(ListNodePosi(T) &p, int n){
    if (n < 2) return;//若待排序范围已足够小,则直接返回;否则...
    int m = n >> 1;//以中点为界
    ListNodePosi(T) q = p;
    for (int i = 0; i < m; i++)q = q->succ;//均分列表
    mergeSort(p, m); mergeSort(q, n - m);//对前、后子列表分别排序
    merge(p, m, *this, q, n - m);//归并
}//注意:排序后,p依然指向归并后区间的(新)起点
//判断列表是否有序
template<typename T>
int List<T>::disordered()const{
    int n=0;
    for (ListNodePosi(T) p = header->succ; p->succ != trailer; p = p->succ){
        if (p->data > p->succ->data)
            n++;
    }
    return n;
}//返回0表示已有序
#endif // !LIST_H

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值