带哨兵节点的链_继续做双向链表,带头尾哨兵的。

// ListNode.hpp

///

#pragma once

#define NULL 0

template

struct ListNode {

ListNode() : pred(NULL), succ(NULL) { }

ListNode(T e, ListNode* p = NULL, ListNode* s = NULL)

: pred(p), succ(s), data(e) { }

ListNode* insertAsPred(T const& e);

ListNode* insertAsSucc(T const& e);

ListNode* pred;

ListNode* succ;

T data;

};

template

ListNode* ListNode::insertAsPred(T const& e) {

auto x = new ListNode(e, pred, this); //创建新节点

if (!x) return NULL;

pred->succ = x; //设置正向链接

pred = x;

return x; //返回新节点的位置

}

template

ListNode* ListNode::insertAsSucc(T const& e) {

auto x = new ListNode(e, this, succ); //创建新节点

if (!x) return NULL;

succ->pred = x; //设置逆向链接

succ = x;

return x; //返回新节点的位置

}

// List.hpp

/

#pragma once

#include "ListNode.h"

template

struct ListNode;

template

class list {

public:

list() { init(); }

list(ListNode* p, int n);

list(list const& lst);

list(list const& lst, int r, int n);

~list();

public:

bool valid(ListNode* p);

int size() { return _size; }

bool empty() { return _size <= 0; }

ListNode * first() const { return _head->succ; }

ListNode * last( ) const { return _tail->pred; }

T& operator[](int r) const;

// 无序链表中的查找

ListNode* find(T const& e, int n = size(), ListNode* p = tail()) const;

// 有序链表中的查找

ListNode* search(T const& e, int n = size(), ListNode* p = tail()) const;

ListNode* insertAsLast(T const& e);

ListNode* insertAsFirst(T const& e);

ListNode* insertAfter(T const& e, ListNode* p);

ListNode* insertBefore(T const& e, ListNode* p);

T remove(ListNode* p);

int remove(T const& e, bool bDelSame = false);

int duplicate();

int uniquify();

void travel();

void reverseAboutMid(); // 关于中间对称轴颠倒节点

void reverseAdjacent(); // 颠倒两两相邻的节点

void reverseAround(); // 整个链表的颠倒

protected:

void init();

int clear();

ListNode* head() { return _head; }

ListNode* tail() { return _tail; }

void copyNodes(ListNode* p, int n);

private:

int _size;

ListNode* _head; // 头哨兵

ListNode* _tail; // 尾哨兵

};

template

list::~list() {

clear();

delete _head;

delete _tail;

_size = 0;

_head = _tail = NULL;

}

template

list::list(ListNode* p, int n) {

copyNodes(p, n);

}

template

list::list(list const& lst) {

copyNodes(lst.header, lst.size());

}

template

list::list(list const& lst, int r, int n) {

copyNodes(list[r], n);

}

template

void list::init() {

_head = new ListNode;

_tail = new ListNode;

_head->succ = _tail;

_head->pred = NULL;

_tail->succ = NULL;

_tail->pred = _head;

_size = 0;

}

template

T& list::operator[](int r) const {

ListNode* p = first();

while (0 < r--) p = p->succ;

return p->data;

}

template

bool list::valid(ListNode* p) {

if (p == head() || p == tail())

return false;

return true;

}

template

ListNode* list::find(T const& e, int n, ListNode* p) const {

while (0 <= n--) // [0, n - 1)

if (e == (p = p->pred)->data) break;

if (!valid(p))

return NULL;

return p;

}

template

ListNode* list::search(T const& e, int n, ListNode* p) const {

while (0 <= n--) // [0, n)

if (e >= ((p = p->pred)->data))

break;

if (!valid(p))

return NULL;

return p;

}

template

ListNode* list::insertAsFirst(T const& e) {

_size++;

return head()->insertAsSucc(e);

}

template

ListNode* list::insertAsLast(T const& e) {

_size++;

return tail()->insertAsPred(e);

}

template

ListNode* list::insertAfter(T const& e, ListNode* p) {

_size++;

return p->insertAsSucc(e);

}

template

ListNode* list::insertBefore(T const& e, ListNode* p) {

_size++;

return p->insertAsPred(e);

}

template

void list::copyNodes(ListNode* p, int n) {

init();

for ( ; n--; p = p->succ)

insertAsLast(p->data);

}

template

T list::remove(ListNode* p) {

T e = p->data;

p->succ->pred = p->pred;

p->pred->succ = p->succ;

delete p;

_size--;

return e;

}

template

int list::remove(T const& e, bool bDelSame) {

int nSize = 0;

if (!(nSize = size())) return 0;

for (auto p = head(), q = p->succ; q; q = q->succ) {

while (p->data == e || q->data == e) {

if (p->data == e) {

remove(p); // 删除符合条件的前驱节点

p = q; // 用后继节点的地址更新前驱节点的地址

}

else if (q->data == e) {

remove(q); // 删除符合条件的后继节点

q = p->succ; // 用前驱的后继节点的地址更新后驱节点的地址

}

else if (q == tail()) break;

}

}

return nSize - size();

}

template

int list::clear() {

int tmp = size();

while (!empty())

remove(head()->succ);

return tmp;

}

template

int list::duplicate() {

if (size() < 2) return 0;

int tmp = size();

auto p = head;

int r = 0;

while (tail() != (p = p->succ)) {

auto q = find(p->data, r, p);

q ? remove(q) : r++;

}

return tmp - size();

}

template

int list::uniquify() {

if (size() < 2) return 0;

int tmp = size();

auto p = first(), q = last();

while (tail() != (q = p->succ))

if (p->data != q->data) p = q;

else remove(q);

return tmp - size();

}

template

void list::reverseAboutMid() {

auto p = head(), q = tail();

for (int i = 1; i < size(); i += 2)

swap((p = p->succ)->data, (q = q->pred)->data);

}

template

void list::reverseAdjacent() {

if (size() < 2) return;

for (auto p = head(); p; p = p->succ)

swap(p->pred, p->succ);

swap(head, tail);

}

template

void list::reverseAround() {

if (size() < 2) return;

for (auto p = head(), q = p->succ; p != tail(); p = q, q = q->succ)

p->pred = q;

tail()->pred = NULL;

for (auto p = tail(), q = p->pred; p != head(); p = q, q = q->pred)

q->succ = p;

head()->succ = NULL;

}

#include

using namespace std;

template

void list::travel() {

for (auto p = first(); p != tail(); p = p->succ)

cout << "[ " << p->data << " ]" << " " << "[ " << p << " ]" << endl;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值