#include <iostream>
using namespace std;
// 数据类型
typedef int DataType;
// 定义节点
struct Node
{
// 构造函数
Node(DataType data = 0)
:my_data(data)
,pPre(NULL)
,pNext(NULL)
{}
DataType my_data; // 结点数据
Node* pPre; // 指向前一个节点的指针
Node* pNext; // 指向下一个节点的指针
};
// 双向链表类
class List
{
private:
Node* pHead; // 头指针
Node* pTail; // 尾指针
size_t size; // 当前元素个数
public:
// 构造函数
List()
:pHead(NULL)
,pTail(NULL)
,size(0)
{}
// 拷贝构造函数
List(const List &list)
:pHead(NULL)
,pTail(NULL)
,size(0)
{
Node *tempNode = list.pHead;
for(size_t i = 0; i < list.size; i++)
{
PushBack(tempNode->my_data);
tempNode = tempNode->pNext;
}
}
// 赋值运算符重载
List& operator=(const List &l)
{
if (this->pHead != l.pHead) // 判断是否是自己给自己赋值
{
Node* tempNode = l.pHead;
if (NULL != pHead)
{
Clear(); // 释放掉原来的空间
}
for (size_t i = 0; i < l.size; i++) // 插入元素
{
PushBack(tempNode->my_data);
tempNode = tempNode->pNext;
}
}
return *this;
}
~List()
{
Clear();
}
// 清空链表
void Clear()
{
Node *curNode = this->pHead;
Node *curNext = this->pHead;
while (curNext)
{
curNext = curNext->pNext;
delete curNode;
curNode = curNext;
}
pTail = pHead = NULL;
size = 0;
}
// 尾插
void PushBack(const DataType &value)
{
// 链表为空时
if (this->size == 0)
{
pHead = pTail = BuyNode(value);
}
else // 不为空时
{
Node * tempNode = BuyNode(value);
pTail->pNext = tempNode;
tempNode->pPre = pTail;
pTail = tempNode;
}
++size;
}
// 尾删
void PopBack()
{
// 为空时
if (0 == this->size)
{
return;
} // 只有一个节点时
else if(1 == this->size)
{
delete pHead;
pHead = pTail = NULL;
size = 0;
} // 多个节点
else
{
pTail = pTail->pPre;
delete pTail->pNext;
pTail->pNext = NULL;
--size;
}
}
// 头插
void PushFront(const DataType &value)
{
if (0 == this->size)
{
pHead = pTail = BuyNode(value);
}
else
{
Node *newNode = BuyNode(value);
newNode->pNext = pHead;
pHead->pPre = newNode;
pHead = newNode;
}
++size;
}
// 头删
void PopFront()
{
if (0 == this->size)
{
return;
}
else if (1 == this->size)
{
delete pHead;
pHead = pTail = NULL;
--size;
}
else
{
pHead = pHead->pNext;
delete pHead->pPre;
pHead->pPre = NULL;
--size;
}
}
// 查找一个元素 存在返回节点 不存在返回null
Node* Find(const DataType &value)const
{
Node * tempNode = this->pHead;
while (tempNode)
{
if (value == tempNode->my_data)
{
return tempNode;
}
tempNode = tempNode->pNext;
}
return NULL;
}
// 给的位置插入一个节点
void Insert(Node* pos, const DataType &value)
{
// 拦截位置为空
if (NULL == pos)
{
return;
} // 位置尾节点时
else if(pos == this->pTail)
{
PushBack(value);
}
else
{
// 默认插入到给定位置后面
Node* tempNode = BuyNode(value);
tempNode->pNext = pos->pNext;
pos->pNext->pPre = tempNode;
tempNode->pPre = pos;
pos->pNext = tempNode;
++size;
}
}
// 删除一个节点
void Erase(Node *pos)
{
// 位置为空 时候
if ( NULL == pos)
{
return;
}
else if(pos == this->pTail) // 分别处理头和尾节点是因为 多个节点处理的时候会用到前后两个位置 也就是大于等于3个结点的情况
{
PopBack();
}
else if (pos == this->pHead)
{
PopFront();
}
else
{
pos->pNext->pPre = pos->pPre;
pos->pPre->pNext = pos->pNext;
delete pos;
pos = NULL;
--size;
}
}
// 判断是否为空
bool Empty()const
{
return 0 == this->size;
}
// 返回节点个数
size_t Size()const
{
return this->size;
}
//返回第一个结点元素
Node& Front()
{
return *pHead;
}
const Node& Front()const
{
return *pHead;
}
//返回第一个结点元素
Node& Back()
{
return *pTail;
}
const Node& Back()const
{
return *pTail;
}
private:
Node* BuyNode(const DataType &value)const
{
return new Node(value);
}
};
int main()
{
List testList;
// 测试尾插
testList.PushBack(1);
testList.PushBack(2);
testList.PushBack(3);
// 测试返回头结点
// cout<< testList.Front().my_data << endl;
// 测试返回尾结点
// cout << testList.Back().my_data << endl;
// 测试元素个数
// cout << testList.Size() << endl;
// 测试是否为空
// cout << testList.Empty() << endl;
// 测试删除元素
// testList.Erase(testList.Find(1));
// testList.Erase(testList.Find(2));
// testList.Erase(testList.Find(3));
// testList.Erase(testList.Find(8));
// 测试插入节点
testList.Insert(testList.Find(3), 9);
// testList.Insert(testList.Find(1), 8);
// 测试查找元素
// cout << testList.Find(8) << endl;
// cout << testList.Find(1) << endl;
// 测试头删
// testList.PopFront();
// testList.PopFront();
// testList.PopFront();
// testList.PopFront();
// 测试头插
// testList.PushFront(0);
// testList.PushFront(-1);
// testList.PushFront(-2);
// 测试尾删
// testList.PopBack();
// testList.PopBack();
// testList.PopBack();
// 测试拷贝构造函数
// List l2(testList);
// l2.PushBack(4);
// l2.PushBack(5);
// 测试赋值运算符重载
// l2 = testList;
return 0;
}
【c++】实现双向链表List类及测试
最新推荐文章于 2022-03-05 15:54:18 发布