课程笔记 08:数据结构(清华) 列表-读写接口

在介绍循位置访问、查找元素等只读操作以及插入、删除、去重等可写操作前,先讲讲初始化方法与复制构造函数的实现。


void List::init()

{

header = new ListNode<T>;

tailor = new ListNode<T>;

header.succ = tailor; header.pred  = NULL;

tailor.pred = header; tailor.succ = NULL;

_size = 0;

}

而复制函数的实现如下:

void List<T>::copyNodes(ListNodePosi(T) p, int n) //p合法,且至少有n-1个真后继节点

init(); //创建头、尾哨兵节点并做初始化

while ( n -- ) //将起自p起的n项依次作为末节点插入

{

insertAsLast(p.data);

p = p.succ;

}

以下是基于复制方法的初始化:

List<T>::List(ListNodePosi(T) p, int n) 

{ copyNodes(p, n); } //复制列表中自位置p起的n项

List<T>::List(List<T> const& L)

{ copyNodes(L.first(), L._size); } //整体复制列表L

List<T>::List(List<T> const& L, int r, int n)

{ copyNodes(L[r], n); }


为了延续向量中循秩访问的形式,我们需要重载[]操作符。

T & List::operator[](Rank r)

{

ListNodePosi(T) p = first();

while (-- r) p = p.succ;

return p.data;

}


针对无序列表的查找功能实现如下:

ListNodePosi(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越出左边界意味着区间内不含e,查找失败

};


列表的插入分为以下几种。

ListNodePosi(T) List<T>::insertAsFirst(T const& e) //e当作首节点插入

{ _size++; return header->insertAsSucc(e); }

ListNodePosi(T) List<T>::insertAsLast(T const& e)

{ _size++; return trailer->insertAsPred(e); } //e当作末节点插入

ListNodePosi(T) List<T>::insertBefore(ListNodePosi(T) p, T const& e)

{ _size++; return p->insertAsPred(e); } //e当作p的前驱插入

ListNodePosi(T) List<T>::insertAfter(ListNodePosi(T) p, T const& e)

{ _size++; return p->insertAsSucc(e); } //e当作p的后继插入


删除算法的实现如下:

T List<T>::remove(ListNodePosi(T) p) //删除除合法位置p处节点,返回回其数值

{

T e = p->data; //备份待删除节点的数值(假定T类型可直接赋值)

p->pred->succ = p->succ; p->succ->pred = p->pred; //后继、前驱

delete p; _size--; //释放节点,更新规模

return e; //返回备份的数值

}


以下是无序列表的去重操作:

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; //列表规模变化量,即被删除元素总数

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值