单链表的结构有多种
这里介绍的链表有头结点、有尾节点并且尾节点指向头结点
#include<iostream>
using namespace std;
#include<assert.h>
typedef int DataType;
struct LinkNode
{
friend class SList; //将SList设为友元,便于SList类可以访问节点类的私有成员
public:
LinkNode(const DataType x)
:_data(x)
, _next(NULL)
{}
private:
DataType _data; //节点的数据
LinkNode* _next; //指向该节点的下一个节点
};
class SList
{
public:
SList() //构造函数
:_head(NULL)
, _tail(NULL)
{}
SList(const SList& s) //拷贝构造
:_head(NULL)
, _tail(NULL)
{
LinkNode* tmp = s._head;
do{
PushBack(tmp->_data);
tmp = tmp->_next;
} while (tmp != s._head);
}
SList &operator=(const SList& s) //赋值运算符的重载
{
if (this != &s)
{
_head = NULL;
_tail = NULL;
LinkNode* tmp = s._head;
do{
PushBack(tmp->_data);
tmp = tmp->_next;
} while (tmp != s._head);
}
}
~SList() //析构
{
Clear();
}
public:
void PrintSList() //打印链表
{
//头结点为空时,无需打印链表
if (_head==NULL)
{
cout << "This SList is Empty !" << endl;
return;
}
else
{
LinkNode* tmp = _head;
do{
cout << tmp->_data << "-->";
tmp = tmp->_next;
} while (tmp != _head);
cout << endl;
}
}
void PushBack(const DataType& x) //在尾部插入一个节点
{
//如果链表为空,插入节点后只有一个节点,此时_head=_tail
if (_head == NULL)
{
_head = new LinkNode(x);
_tail = _head;
_tail->_next = _head;
}
else
{
_tail->_next = new LinkNode(x);
_tail = _tail->_next;
_tail->_next = _head;
}
}
void Clear() //链表置空
{
LinkNode* begin = _head;
while (begin != _tail)
{
_head = _head->_next;
delete begin;
begin = _head;
}
_head = NULL;
_tail = NULL;
}
void PopBack() //尾删
{
if (_head == NULL)
{
cout << "This SList is empty !" << endl;
}
else if (_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
LinkNode* cur = _head;
while (cur->_next != _tail)
{
cur = cur->_next;
}
delete _tail;
_tail = cur;
_tail->_next = _head;
}
}
void PushFront(DataType x) //头插
{
if (_head == NULL)
{
PushBack(x);
}
else
{
LinkNode* tmp = _head;
_head = new LinkNode(x);
_head->_next = tmp;
_tail->_next = _head;
}
}
void PopFront() //删除首节点
{
if (_head == NULL)
{
cout << "This SList is empty !" << endl;
return;
}
LinkNode* tmp = _head;
_tail->_next = _head;
delete tmp;
}
//固定位置插入一个节点(这个函数需和Find函数搭配使用)
//先用Find函数找到新节点需要插入的位置,即
//(将Find函数的返回值传给Insert函数的参数pos),再在pos节点后面插入新节点x
void Insert(LinkNode* pos, DataType x)
{
assert(pos);
if (pos==_tail)
{
PushBack(x);
}
else
{
LinkNode* tmp = new LinkNode(x);
tmp->_next = pos->_next;
pos->_next = tmp;
}
}
//删除某一节点,同样,要先找到该节点并传参给Erase函数
void Erase(LinkNode* pos)
{
assert(pos);
if (pos == _tail)
{
PopBack();
}
if (pos == _head)
{
PopFront();
}
else
{
LinkNode* prev = _head;
while (prev->_next != pos)
{
prev = prev->_next;
}
prev->_next = pos->_next;
delete pos;
}
}
LinkNode* Find(DataType x) //查找节点并返回这个节点的地址
{
if (_head == NULL)
{
cout << "This SList is empty !" << endl;
return NULL;
}
else
{
LinkNode* tmp = _head;
do{
if (tmp->_data == x)
{
return tmp;
}
tmp = tmp->_next;
} while (tmp != _head);
return NULL;
}
}
int Amount() //计算链表节点的数目
{
if (_head == NULL)
{
return 0;
}
else
{
int count = 0;
LinkNode* cur = _head;
while (cur != _tail)
{
count++;
cur = cur->_next;
}
return ++count;
}
}
void Remove(DataType x) //查找某节点并删除
{
if (_head == NULL)
{
cout << "This SList is empty !" << endl;
}
else
{
LinkNode* tmp = Find(x);
if (tmp != NULL)
{
Erase(tmp);
}
}
}
void RemoveAll(DataType x) //删除链表中所有的x
{
if (_head == NULL)
{
cout << "This SList is empty !" << endl;
return;
}
//如果链表不为空,
//从头至尾遍历一遍,delete节点的data为x的节点
LinkNode* left = _tail;
LinkNode* right = _head;
int count = Amount();
while (count--)
{
if (right->_data == x)
{
//当要删掉的节点是头节点时,
//需要注意头节点要指向它的下一个节点
if (_head == right)
{
_head = _head->_next;
}
//当要删掉的节点是尾节点时,
//需要注意尾节点要指向它的上一个节点
if (_tail == right)
{
_tail =left;
}
//当left和right指向同一块要删掉的节点时,
//将链表置空
if (right == left)
{
_head = NULL;
_tail = NULL;
return;
}
LinkNode* tmp = right;
right = right->_next;
delete tmp;
left->_next = right;
}
else
{
left = right;
right = right->_next;
}
}
}
private:
LinkNode* _head;
LinkNode* _tail;
};
void Test2()
{
SList list1;
list1.PushBack(2);
list1.PushBack(3);
list1.PushBack(4);
list1.PushBack(2);
list1.PushBack(2);
list1.PrintSList();
list1.RemoveAll(2);
list1.PrintSList();
}
void Test1()
{
//SList list1;
//list1.PushBack(1);
//list1.PushBack(2);
//list1.PushBack(3);
//list1.PushBack(4);
//list1.PushBack(5);
//list1.PrintSList();
//list1.Remove(2);
//list1.PrintSList();
//int num =list1.Amount();
//cout <<"节点个数:"<< num << endl;
/*//检验Erase函数
LinkNode* del = list1.Find(2);
list1.Erase(del);
list1.PrintSList();
*/
/*//找到某节点并在其后插入新节点
LinkNode* In =list1.Find(5);
list1.Insert(In, 0);
list1.PrintSList();*/
/* //删除头结点
list1.PopFront();
list1.PrintSList();
*//////
/*//////查找节点
LinkNode* ret=list1.Find(5);
if (ret != NULL)
{
cout << "要查找的节点data是:" << ret->_data << endl;
cout << "要查找的节点adress是:" <<ret<< endl;
}
else
{
cout << "not exit !" << endl;
}*////////
//验证构造函数
//SList list2(list1);
//list2.PrintSList();
//验证赋值运算符的重载
//SList list3 = list2;
//list3.PrintSList();
//验证析构函数
//list3.Clear();
//list3.PrintSList();
//验证尾删和头插
///*list3.PopBack();
//list3.PrintSList();*/
//list3.PushFront(0);
//list3.PrintSList();
}
int main()
{
//Test1();
Test2();
system("pause");
}本文出自 “言安阳” 博客,谢绝转载!
原文地址:http://iynu17.blog.51cto.com/10734157/1752937