您的位置:首页 > 其它

线性表链接实现--双循环链表

2013-05-07 22:47 316 查看
                    在实现时没有引入两个辅助节点,所以实现时需要考虑特殊情况,比如头和尾插入删除操作时,需要改变指向头和尾的指针。在做迭代器的时候还有麻烦,遍历链表时需要借助量表的长度,不然不能标识结束,我想到的办法是在迭代器中做一些记录工作,比如当前的下标和整个链表的长度。有解决办法的希望指教。

                   

#ifndef LINKLIST_H
#define LINKLIST_H
#include "list.hpp"

template <typename T>
struct node {
T d;
node *pre, *next;
node(const T& _d, node *_pre = NULL, node *_next = NULL):
d(_d),
pre(_pre),
next(_next) {

}
};

template <typename T>
class LinkList : public List<T>
{
public:
/**
* @brief The Iterator class 双循环链表设计时没有头和尾节点,所以在设计迭代器时不方便,比如遍历链表必须借助链表的长度
*/
class Iterator
{
friend std::ostream& operator << (std::ostream &os, const Iterator &obj) {
os << obj.p->d;
return os;
}
public:
Iterator(node<T> *_p):p(_p){}
~Iterator(){}
Iterator(const Iterator& obj):p(obj.p){}
Iterator& operator = (const Iterator& obj) {
p = obj.p;
return *this;
}

Iterator& operator ++() {
p = p->next;
return *this;
}
Iterator operator ++(int) {
Iterator t(p);
p = p->next;
return  t;
}
Iterator& operator -- (){
p = p->pre;
return *this;
}
Iterator operator -- (int) {
Iterator t(p);
p = p->pre;
return  t;
}
T operator * () {
return p->d;
}
T* operator -> () {
return &p->d;
}

bool operator == (const Iterator &ite) {
return p == ite.p;
}

bool operator != (const Iterator &ite) {
return p != ite.p;
}
private:
node<T> *p;
};
LinkList():head(NULL),tail(NULL),size(0) {}
~LinkList();
void clear();
int length() const;
/**
* @brief insert 插入到链表的指定位置 插入i的下个位置
* @param i 下标 从0开始
* @param t
*/
void insert(int i, const T &t);
int search(const T &t) const;
T visit(int i) const;
void traverse(std::ostream &os = std::cout) const;
void remove(int i);
void add(const T& o);
void push_front(const T& o);
void push_tail(const T& o);
T pop_front();
T pop_tail();
Iterator begin() const {
return Iterator(head);
}
private:
node<T> *head, *tail;
int size;
node<T>* local(int i) const;
};

template <typename T>
LinkList<T>::~LinkList()
{
clear();
}

template <typename T>
/**
* @brief LinkList<T>::add 在双循环链表的tail添加节点
* @param o
*/
void LinkList<T>::add(const T &o)
{
node<T> *p = NULL;
if (size == 0) {
p = new node<T>(o);
head = tail = p;
head->pre = tail;
tail->next = head;
} else {
p = new node<T>(o,tail,head);
head->pre = p;
tail->next = p;
tail = p;
}
++size;
}

template <typename T>
node<T> *LinkList<T>::local(int i) const
{
if (i < 0 ||i > size - 1) throw BadValue();
node<T> *p = head;
for (int j = 0;j < i;++j) {
p = p->next;
}
return p;
}

template <typename T>
/**
* @brief LinkList<T>::clear 只有一个节点
*/
void LinkList<T>::clear()
{
node<T> *p = head;
while(size--) {
head = head->next;
delete p;
p = head;
}
head = tail = NULL;
size = 0;
}

template <typename T>
/**
* @brief LinkList<T>::insert 插在i的后面
* @param i
* @param t
*/
void LinkList<T>::insert(int i, const T &t)
{
if ((size == 0 && i == 0) || size-1 == i) {//过滤掉空链表插入和尾部插入
add(t);
} else {
node<T> *p = local(i);//i节点
node<T> *n = p->next;//下个节点
node<T> *d = new node<T>(t,p,n);
p->next = d;
n->pre = d;
++size;
}

}

template <typename T>
int LinkList<T>::length() const
{
return size;
}

template <typename T>
int LinkList<T>::search(const T &t) const
{
int re = -1;
node<T> *p = head;
for (int i = 0;i < size;++i) {
if (p->d == t) {
re = i;
break;
}
p = p->next;
}
return re;
}

template <typename T>
T LinkList<T>::visit(int i) const
{
return local(i)->d;
}
template <typename T>
void LinkList<T>::remove(int i)
{
node<T> *p = local(i);
p->pre->next = p->next;
p->next->pre = p->pre;
--size;
if (i == 0) {
head = p->next;
tail->next = head;
}
if (i == size-1) {
tail = p->pre;
head->pre = tail;
}
delete p;
}

template <typename T>
void LinkList<T>::traverse(std::ostream &os) const
{
node<T> *p = head;
for (int i = 0;i < size;++i) {
os << p->d << "    ";
p = p->next;
}

}

template <typename T>
/**
* @brief LinkList<T>::push_front 插入头部
* @param o
*/
void LinkList<T>::push_front(const T &o)
{
node<T> *p = new node<T>(o,tail,head);
p->next =head;
p->pre = tail;
head = p;
++size;

}
template <typename T>
void LinkList<T>::push_tail(const T &o)
{
add(o);
}

template <typename T>
T LinkList<T>::pop_front()
{
T t = local(0)->d;
remove(0);
return t;
}
template <typename T>
T LinkList<T>::pop_tail()
{
T t = local(size-1)->d;
remove(size-1);
return t;
}

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: