c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)
本文主要内容
1)介绍c++中双向链表的写法。
2)实现双向链表中数据的增、删、查、改、链表逆置、链表输出
3)介绍类中构造函数、析构函数、运算符重载函数的写法
接下来介绍双向链表的成员函数:这写函数放在头文件中,方便编写
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
typedef int DataType;
class ListNode //节点
{
public:
ListNode(DataType x)
:_data(x),
_next(NULL),
_prev(NULL)
{}
ListNode*_next;
ListNode*_prev;
DataType _data;
};
class List //双向链表
{
public:
List();
List(List&s);
List&operator=(const List&s);
~List();
void PushBack(DataType x);
void PopBack();
void PushFront(DataType x);
void PopFront();
void Insert(ListNode *pos, DataType x);
void Erase(ListNode*pos);
ListNode* Find(DataType x);
void Reverse();
void PrintList();
void Clear();
void PrintReverseList();
private:
ListNode*_head;
ListNode* _tail;
};
接下来介绍各个函数,
1)构造函数(此处写了一种,因为只用到了这一种)
List::List()
:_head(NULL),
_tail(NULL)
{}
2)构造函数中的拷贝构造
List::List(List&s)
:_head(NULL),
_tail(NULL)
{
ListNode*cur = s._head;
while (cur)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
3)赋值运算符重载
List& List::operator=(const List&s)
{
_head = NULL;
_tail = NULL;
ListNode*cur = s._head;
while (cur)
{
PushBack(cur->_data);
cur = cur->_next;
}
return *this;
}
4)析构函数
List::~List()
{
Clear();
}
void List::Clear()
{
cout << "~Clear() ";
ListNode*cur = _head;
while (cur)
{
ListNode*del = cur;
cur = cur->_next;
delete del;
}
cout << " clear is NULL" << endl;
}
5)增加节点的函数(三种,前增、后增、给定节点后插入)
void List::PushFront(DataType x)
{
if (_head == NULL)
{
_head = new ListNode(x);
_tail = _head;
}
else
{
ListNode*temp = new ListNode(x);
_head->_prev = temp;
temp->_next = _head;
_head = temp;
}
}
void List::PushBack(DataType x)//后增
{
if (_head == NULL)
{
_head = new ListNode(x);
_tail = _head;
}
else
{
ListNode*temp = new ListNode(x);
_tail->_next = temp;
temp->_prev = _tail;
_tail = temp;
}
}
void List::Insert(ListNode *pos, DataType x)
{
assert(pos);
if (pos == _tail)
{
PushBack(x);
}
else
{
ListNode*cur = pos->_next;
ListNode*temp = new ListNode(x);
temp->_next = cur;
temp->_prev = pos;
pos->_next = temp;
cur->_prev = temp;
}
}
6)删除节点(三种,前删、后删、删除给定节点)
void List::PopFront()
{
if (_head == NULL)
{
cout << "空链表!" << endl;
return;
}
else
{
if (_head->_next)
{
ListNode *temp = _head;
_head = _head->_next;
_head->_prev = NULL;
delete temp;
}
else
{
delete _head;
_head = _tail = NULL;
}
}
}
void List::PopBack()
{
if (_head == NULL)
{
cout << "空链表!" << endl;
return;
}
else
{
if (_tail->_prev)
{
ListNode *temp = _tail;
_tail = _tail->_prev;
_tail->_next = NULL;
delete temp;
}
else
{
delete _tail;
_head = _tail = NULL;
}
}
}
void List::Erase(ListNode*pos)
{
assert(pos);
if (pos == _head)
{
PopFront();
}
else if (pos == _tail)
{
PopBack();
}
else
{
ListNode*temp = pos->_prev;
ListNode*next = pos->_next;
temp->_next = next;
next->_prev = temp;
delete pos;
}
}
7)寻找节点
ListNode* List::Find(DataType x)
{
if (_head == NULL)
{
cout << "空链表!" << endl;
return NULL;
}
ListNode*cur = _head;
while (cur)
{
if (cur->_data == x)
return cur;
cur = cur->_next;
}
}
8)双向链表逆置(两种方法)
方法一:交换每个节点的前驱和后继。
方法二:创建新的链表,从远链表上摘节点然后补到新链表上
//void List::Reverse() //方法 一
//{
// if (_head == NULL)
// {
// cout << "空链表!" << endl;
// return;
// }
// else if (_head == _tail)
// return;
// else
// {
// swap(_tail,_head);
// ListNode *cur = _head;
// while (cur)
// {
// swap(cur->_prev, cur->_next);
// cur = cur->_next;
// }
// }
//}
void List::Reverse()//方法二
{
if (_head == NULL)
{
cout << "空链表!" << endl;
return;
}
else if (_head == _tail)
return;
else
{
ListNode*cur = _tail;
ListNode *newhead = NULL;
while (cur)
{
if (newhead == NULL)
{
newhead = new ListNode(cur->_data);
_head = newhead;
}
else
{
ListNode*temp = new ListNode(cur->_data);
newhead->_next = temp;
temp->_prev = newhead;
newhead = temp;
_tail = temp;
}
ListNode* del = cur;
cur = cur->_prev;
delete del;
}
}
}
9)打印链表(两种,顺序打印、逆序打印)
void List::PrintList()//顺序打印
{
ListNode*cur = _head;
while (cur)
{
cout << cur->_data << "->";
cur = cur->_next;
}
cout << "NULL" << endl;
}
void List::PrintReverseList()//逆序打印
{
cout << "从后向前:";
ListNode*cur = _tail;
while (cur)
{
cout << cur->_data << "->";
cur = cur->_prev;
}
cout << "NULL" << endl;
}
当然还有主函数(测试用例)
#include"List.h"
void Test3()
{
cout << endl;
List l1;
l1.PushFront(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.PushBack(5);
l1.PushBack(6);
//l1.PushFront(4);
//l1.PopFront();//前删
//l1.PopBack();//后删
//ListNode *pos = l1.Find(3);
//l1.Insert(pos, 5);
//l1.Erase(pos);
cout << "l1 :";
l1.PrintList();
l1.PrintReverseList();
cout << "逆置l1 :";
l1.Reverse();
l1.PrintList();
l1.PrintReverseList();
cout << "拷贝构造-》 l2 :";
List l2(l1);
l2.PrintList();
cout << "赋值运算符重载 -》 l3 :";
List l3;
l3 = l2;
l3.PrintList();
}
int main()
{
Test3();
system("pause");
return 0;
}
以上函数均是在学习的过程中总结写出的,肯定会有一些疏漏或者错误之处,所以敬请各位大神的批评指正,谢谢
转载于:https://blog.51cto.com/xmwen1/1748216