C++实现双向循环链表

/***********双向循环链表(代码调试正常,所有功能均测试)*************/

//节点类

template

class ListNode

{

public:

Type data;//节点数据域

ListNode *next;//后继指针

ListNode *prev;//前驱指针

ListNode() :data(Type()), next(nullptr), prev(nullptr){}

ListNode(Type d, ListNode *n = nullptr, ListNode *p = nullptr) : data(d), next(n), prev(p){}

void SetData(Type d){ this->data = d; }

};

//双向循环链表:主要注意尾指针的调节

template

class DoubleList

{

private:

ListNode *head;//链表头指针

ListNode *tail;//链表尾指针

int length;//链表长度

public:

DoubleList();

~DoubleList();

bool isEmpty(){ return this->length == 0; }

int size(){ return this->length; }

bool push_front(const Type &x);

bool push_back(const Type &x);

bool push_val(int k, const Type &x);//在链表第K个位置插入元素X

bool pop_front();

bool pop_back();

bool pop_data(int k);//删除第k个节点

bool find(int k, Type &x) const;

void reserse();

void show_list() const;

};

//构造函数

template

DoubleList::DoubleList()

{

cout << “构造函数(空链表,包含一个头节点)” << endl;

this->head = this->tail = new ListNode();

this->head->prev = this->tail;

this->tail->next = this->head;

this->length = 0;

}

//析构函数

template

DoubleList::~DoubleList()

{

cout << “析构函数,删除所有节点” << endl;

ListNode *pdelete, *ptemp;

pdelete = this->head->next;

while (pdelete != this->head)

{

ptemp = pdelete->next;

this->head->next = ptemp;

ptemp->prev = this->head;

delete pdelete;

pdelete = ptemp;

}

delete this->head;

}

//头插

template

bool DoubleList::push_front(const Type &x)

{

ListNode *temp = new ListNode(x, nullptr, nullptr);//创建一个节点

if (temp == nullptr)

return false;

if (this->length == 0)//判断this->head->prev==this->head

{

this->head->next = temp;

temp->prev = this->head;

this->tail = temp;

this->tail->next = this->head;

this->head->prev = this->tail;

this->length++;

return true;

}

temp->next = this->head->next;

this->head->next->prev = temp;

temp->prev = this->head;

this->head->next = temp;

this->length++;

return true;

}

//尾插

template

bool DoubleList::push_back(const Type &x)

{

ListNode *temp = new ListNode(x, nullptr, nullptr);

if (temp == nullptr)

return false;

this->tail->next = temp;

temp->prev = this->tail;

this->tail = temp;

this->tail->next = this->head;

if (this->length == 0)

this->head->prev = this->tail;

this->length++;

return true;

}

//在链表中第k个位置之前,插入新的节点

template

bool DoubleList::push_val(int k, const Type &x)

{

if (k<1 || k>this->length)

{

cout << “插入的数据不在范围内” << endl;

return false;

}

ListNode *temp = new ListNode(x, nullptr, nullptr);//创建一个节点对象

//首先找到第k个节点

ListNode *move = this->head->next;

int i = 1;

while (i < k)

{

move = move->next;

i++;

}

//move是指向第k个节点

move->prev->next = temp;

temp->prev = move->prev;

temp->next = move;

move->prev = temp;

return true;

}

//删除链表开始的节点

template

bool DoubleList::pop_front()

{

if (this->length == 0)

{

cout << “链表为空,无法删除” << endl;

return false;

}

ListNode *temp = this->head->next;//保存第一个节点的地址

this->head->next = temp->next;

temp->next->prev = this->head;

delete temp;

if (this->length == 1)//考虑只有一个元素的特殊情况

this->tail = this->head;

this->length–;

return true;

}

//删除链表最后一个元素

template

bool DoubleList::pop_back()

{

if (this->length == 0)

{

cout << “链表为空,无法删除” << endl;

return false;

}

this->tail->prev->next = this->head;

this->head->prev = this->tail->prev;

delete this->tail;

this->tail = this->head->prev;

this->length–;

return true;

}

//删除第k个节点

template

bool DoubleList::pop_data(int k)

{

if (k<0 || k>this->length)

{

cout << “删除的位置不在范围内,无法删除” << endl;

return false;

}

ListNode *move = this->head->next;

int i = 1;

while (i < k)

{

move = move->next;

i++;

}

if (k == this->length)

{

pop_back();

return true;

}

move->prev->next = move->next;

move->next->prev = move->prev;

delete move;

this->length–;

return true;

}

//查找元素

template

bool DoubleList::find(int k, Type &x) const

{

if (k<1 || k>this->length)

{

cout << “查找元素不在范围内,无法查找” << endl;

x = 0;

return false;

}

ListNode *move = this->head->next;

int i = 1;

while (i < k)

{

move = move->next;

i++;

}

x = move->data;

return true;

}

//逆置链表

template

void DoubleList::reserse()

{

if (this->length == 0 || this->length == 1)

{

cout << “链表中有一个或者链表为空,不需要逆置” << endl;

return;

}

ListNode *s = this->head->next;

ListNode *p = s->next;

s->next = this->head;

this->head->prev = s;

this->tail = s;

while (p != this->head)//注意不能判断p!=nullptr 这样循环永远不会停止,循环链表不可能为nullptr

{

s = p;

p = p->next;

s->next = this->head->next;

this->head->next->prev = s;

this->head->next = s;

s->prev = this->head;

}

}

//输出链表

template

void DoubleList::show_list() const

{

if (this->length == 0)

return;

ListNode *move = this->head->next;

while (move != this->head)

{

cout << move->data << ” “;

move = move->next;

}

cout << endl;

}

//测试程序

int main()

{

DoubleList list;

for (int i = 0; i < 10; i++)

list.push_back(i + 1);

list.show_list();

cout << list.size() << endl;

/*int a;

if (list.find(99, a))

cout << “a=” << a << endl;*/

list.reserse();

list.show_list();

cout << list.size() << endl;

/*list.push_val(5, 10);

list.show_list();

cout << list.size() << endl;*/

/*for (int i = 0; i < 5; i++)

list.pop_front();

list.show_list();

cout << list.size() << endl;*/

//for (int i = 0; i < 5;i++)

// list.pop_back();

//list.show_list();

//cout << list.size() << endl;

//list.pop_data(5);

//list.show_list();

return 0;

}

你可能感兴趣的:(C++数据结构与算法)