您的位置:首页 > 编程语言 > C语言/C++

【C++】实现双向链表的所有操作,包括逆置双链表(三种方法)

2016-03-05 17:02 603 查看
建立源文件List.cpp
include "List.h"

int main()
{
Test();
system("pause");
return 0;
}
建立头文件List.h
#ifndef __LISH_H__
#define __LISH_H__
#include<iostream>
using namespace std;

typedef int DataType;

struct ListNode
{
ListNode(DataType x)
:_next(NULL)
, _prev(NULL)
, _data(x)
{}

ListNode* _next;
ListNode* _prev;
DataType _data;
};

class List
{
public:
List()
:_head(NULL)
,_tail(NULL)
{}

List(const List& s)
:_head(NULL)
, _tail(NULL)
{
ListNode* cur = s._head;
while (cur)
{
this->PushBack(cur->_data);
cur = cur->_next;
}
}

List& operator= (const List& s)
{
//先删除节点,再插入节点
if (&s != this)
{
ListNode* pcur = _head;
while (pcur)
{
ListNode* del = pcur;
pcur = pcur->_next;
delete del;
del = NULL;
}
ListNode* cur = s._head;
while (cur)
{
this->PushBack(cur->_data);
cur = cur->_next;
}
}
return *this;
}

~List()
{
ListNode* cur = _head;
while (cur)
{
ListNode* del = cur;
cur = cur->_next;
delete del;
del = NULL;
}
}

//尾插
void PushBack(DataType x)
{
//分:0节点   1、多节点两种情况
if (_head == NULL)
{
_head = new ListNode(x);
_tail = _head;
_tail->_next = NULL;
}
else
{
ListNode* cur = new ListNode(x);
_tail->_next = cur;
cur->_prev = _tail;
_tail = cur;
_tail->_next = NULL;
}
}

//尾删
void PopBack()
{
if (_head == _tail)
{
if (_head != NULL)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
return;
}
}
else
{
ListNode* prev = _tail->_prev;
delete _tail;
_tail = NULL;
_tail = prev;
_tail->_next = NULL;
}
}

//头插
void PushFront(DataType x)
{
if (_head == NULL)
{
PushBack(x);
}
else
{
ListNode* index = new ListNode(x);
index->_next = _head;
_head->_prev = index;
_head = index;
_head->_prev = NULL;
}
}

//头删
void PopFront()
{
if (_head == _tail)
{
PopBack();
}
else
{
ListNode* del = _head;
ListNode* next = _head->_next;
_head = next;
_head->_prev = NULL;
delete del;
del = NULL;
}
}

//插入元素
void Insert(size_t pos, DataType x)
{
//分:是尾插   不是尾插    两种情况
ListNode* cur = _head;
while (--pos)
{
cur = cur->_next;
}
if (cur == _tail)
{
PushBack(x);
}
else
{
ListNode* index = new ListNode(x);
ListNode* prev = cur->_prev;
index->_next = cur;
cur->_prev = index;
prev->_next = index;
index->_prev = prev;
}
}

//查找元素
ListNode* Find(DataType x)
{
ListNode* cur = _head;
while (cur)
{
if (cur->_data == x)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}

//删除元素
void Erase(ListNode* pos)
{
if (pos == _head)
{
PopFront();
}
else if (pos == _tail)
{
PopBack();
}
else
{
ListNode* prev = pos->_prev;
ListNode* next = pos->_next;
prev->_next = next;
next->_prev = prev;
delete pos;
pos = NULL;
}
}

//逆置方法一:从两头走,交换数据
/*void Reverse()
{
ListNode* begin = _head;
ListNode* end = _tail;
while (!((begin == end) || (end->_next == begin)))
{
swap(begin->_data, end->_data);
begin = begin->_next;
end = end->_prev;
}
}*/

//逆置方法二:交换节点的前驱和后继
/*void Reverse()
{
ListNode* cur = _head;
while (cur)
{
swap(cur->_prev, cur->_next);
cur = cur->_prev;
}
swap(_head, _tail);
}*/

//逆置方法三:摘节点,头插该节点
void Reverse()
{
ListNode* cur = _head;
ListNode* newhead = NULL;
while (cur)
{
ListNode* tmp = cur;
cur = cur->_next;
if (newhead == NULL)
{
newhead = tmp;

newhead->_next = NULL;
newhead->_prev = NULL;
_head = _tail = newhead;
}
else
{
newhead->_prev = tmp;
tmp->_next = newhead;
newhead = tmp;
_head = newhead;
_head->_prev = NULL;
}
}
}

//打印
void PrintList()
{
ListNode* cur = _head;
while (cur)
{
cout << cur->_data << "->";
cur = cur->_next;
}
cout << "NULL" << endl;
}
private:
ListNode* _head;
ListNode* _tail;
};

void Test()
{
List s;
s.PushBack(1);
s.PushBack(2);
s.PushBack(3);
s.PushBack(4);
s.PushBack(5);
s.PrintList();

s.PopBack();
s.PrintList();

s.PushFront(0);
s.PrintList();

s.PopFront();
s.PrintList();

s.Insert(2, 10);
s.PrintList();

s.Reverse();
s.PrintList();

}

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