在我们实现双向链表的增删查改时一定要注意各种情况
分析各种情况我们才能更好的掌握
以下是双向链表增删查改的代码。
#include<iostream>
#include<assert.h>
#include<windows.h>
using namespace std;
typedef int DataType;
struct ListNode
{
ListNode* _next;
ListNode* _prev;
DataType _data;
ListNode(DataType x)
:_data(x)
, _next(NULL)
, _prev(NULL)
{}
};
class List
{
typedef ListNode Node;
public:
List()
:_head(NULL)
, _tail(NULL)
{}
List(const List& l)//拷贝构造
:_head(NULL)
, _tail(NULL)
{
if (l._head == NULL)
{
_head = _tail = NULL;
}
else
{
Node* head = l._head;
while (head)
{
PushBack(head->_data);
head = head->_next;
}
}
}
//l1=l2(传统写法)
List&operator=(const List &l)
{
if (this != &l)
{
this->Clear();
Node*head = l._head;
while (head)
{
PushBack(head->_data);
head = head->_next;
}
return *this;
}
}
//l1=l2(现代写法)
List&operator=(List l)
{
swap(_head, l._head);
swap(_tail, l._tail);
return *this;
}
void Clear()
{
Node*cur = _head;
while (cur)
{
Node*del = cur;
cur = cur->_next;
delete del;
}
_head = _tail = NULL;
}
~List()
{
Clear();
}
//增删查改
void PushBack(DataType x)
{
if (_head==NULL)
{
_head = _tail = new Node(x);
return;
}
else
{
Node *tmp = new Node(x);
_tail->_next = tmp;
tmp->_prev = _tail;
_tail = tmp;
}
}
void PopBack()
{
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node*prev = _tail->_prev;
prev->_next=NULL;
delete _tail;
_tail = prev;
}
}
void PushFront(DataType x)
{
if (_head == NULL)
{
_head = _tail = new Node(x);
}
else
{
Node*tmp = new Node(x);
tmp->_next = _head;
_head->_prev = tmp;
_head = tmp;
}
}
void PopFront()
{
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node*head = _head->_next;
delete _head;
_head = head;
}
}
// 在pos的前面插入一个
void Insert(Node* pos, DataType x)
{
assert(pos);
if (pos == _head)
{
PushFront(x);
}
else
{
Node*tmp = new Node(x);
Node*prev = pos->_prev;
tmp->_next = pos;
pos->_prev = tmp;
prev->_next = tmp;
tmp->_prev = prev;
}
}
Node* Find(DataType x)
{
Node*cur = _head;
while (cur)
{
if (cur->_data == x)
return cur;
}
cur = cur->_next;
}
void Erase(Node* pos)
{
assert(pos);
if (pos == _head)
{
PopFront();
}
else if (pos == _tail)
{
PopBack();
}
else
{
Node*prev = pos->_prev;
Node*next = pos->_next;
prev->_next = next;
next->_prev = prev;
delete pos;
}
}
void Print()
{
Node*cur = _head;
while (cur)
{
cout << cur->_data << " ";
cur = cur->_next;
}
cout << endl;
}
private:
Node* _head;
Node* _tail;
};
第一种情况为交换head,tail
然后head->_next
tail->_prev
直到它们相等或者tail->_next=head
结束循环
void Reverse()
{
Node*head = _head;
Node*tail = _tail;
while (head != tail&&tail->_next != head)
//while(! (head ==tail||tail->_next == head))
{
swap(head->_data, tail->_data);
head = head->_next;
tail = tail->_prev;
}
}
第二种情况如下图,我们将指针进行交换,最后在交换_head与_tail
void Reverse()
{
Node*cur = _head;
while (cur)
{
Node*next = cur->_next;
swap(cur->_next, cur->_prev);
cur = next;
}
swap(_head, _tail);
}
完整版代码如下:
#include<iostream>
#include<assert.h>
#include<windows.h>
using namespace std;
typedef int DataType;
struct ListNode
{
ListNode* _next;
ListNode* _prev;
DataType _data;
ListNode(DataType x)
:_data(x)
, _next(NULL)
, _prev(NULL)
{}
};
class List
{
typedef ListNode Node;
public:
List()
:_head(NULL)
, _tail(NULL)
{}
List(const List& l)
:_head(NULL)
, _tail(NULL)
{
if (l._head == NULL)
{
_head = _tail = NULL;
}
else
{
Node* head = l._head;
while (head)
{
PushBack(head->_data);
head = head->_next;
}
}
}
//l1=l2(传统写法)
List&operator=(const List &l)
{
if (this != &l)
{
this->Clear();
Node*head = l._head;
while (head)
{
PushBack(head->_data);
head = head->_next;
}
return *this;
}
}
//l1=l2(现代写法)
List&operator=(List l)
{
swap(_head, l._head);
swap(_tail, l._tail);
return *this;
}
void Clear()
{
Node*cur = _head;
while (cur)
{
Node*del = cur;
cur = cur->_next;
delete del;
}
_head = _tail = NULL;
}
~List()
{
Clear();
}
void PushBack(DataType x)
{
if (_head==NULL)
{
_head = _tail = new Node(x);
return;
}
else
{
Node *tmp = new Node(x);
_tail->_next = tmp;
tmp->_prev = _tail;
_tail = tmp;
}
}
void PopBack()
{
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node*prev = _tail->_prev;
prev->_next=NULL;
delete _tail;
_tail = prev;
}
}
void PushFront(DataType x)
{
if (_head == NULL)
{
_head = _tail = new Node(x);
}
else
{
Node*tmp = new Node(x);
tmp->_next = _head;
_head->_prev = tmp;
_head = tmp;
}
}
void PopFront()
{
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node*head = _head->_next;
delete _head;
_head = head;
}
}
// 在pos的前面插入一个
void Insert(Node* pos, DataType x)
{
assert(pos);
if (pos == _head)
{
PushFront(x);
}
else
{
Node*tmp = new Node(x);
Node*prev = pos->_prev;
tmp->_next = pos;
pos->_prev = tmp;
prev->_next = tmp;
tmp->_prev = prev;
}
}
Node* Find(DataType x)
{
Node*cur = _head;
while (cur)
{
if (cur->_data = x)
return cur;
}
cur = cur->_next;
}
void Erase(Node* pos)
{
assert(pos);
if (pos == _head)
{
PopFront();
}
else if (pos == _tail)
{
PopBack();
}
else
{
Node*prev = pos->_prev;
Node*next = pos->_next;
prev->_next = next;
next->_prev = prev;
delete pos;
}
}
//逆转方法1
void Reverse()
{
Node*head = _head;
Node*tail = _tail;
while (head != tail&&tail->_next != head)
{
swap(head->_data, tail->_data);
head = head->_next;
tail = tail->_prev;
}
}
//逆转方法2
//void Reverse()
//{
// Node*cur = _head;
// while (cur)
// {
// Node*next = cur->_next;
// swap(cur->_next, cur->_prev);
// cur = next;
// }
// swap(_head, _tail);
//}
void Print()
{
Node*cur = _head;
while (cur)
{
cout << cur->_data << " ";
cur = cur->_next;
}
cout << endl;
}
private:
Node* _head;
Node* _tail;
};
只写了该用的函数,测试函数以及main加在下面就好。