单向循环线性表:也是通过结点的形式在存储器中进行存储,结点包括数据域和指针域,逻辑上相邻的两个结点在物理上不一定相邻,单向循环链式存储的线性表,定义了一个唯一的头结点,头结点的数据域是存储数据的,指针域next指针指向下一个结点,也就是开始结点,定义了一个尾结点,尾结点的next指向头结点,数据域是存储数据的。
#include <iostream>
#include <string>
using namespace std;
typedef int DataType;
struct LinkNode{
DataType _data;
LinkNode* _next;
};
class SList{
public:
SList();
SList(const SList &s);//拷贝构造函数
~SList();//析构函数
public:
//单链表的具体操心
void Uniqe();//去重
void Merge(SList &s);//合并
void Sort();//冒泡
void Reverse();//翻转
void Swap(SList &s);//交换
void PrintSList();//打印链表
void PushBack(const DataType& x);//在尾部插入一个结点
void Clear();//链表置空
void PopBack();//删除尾结点
void PushFront(DataType x);//头插
void PopFront();//删除首节点
void Insert(LinkNode *pos,DataType x);//固定位置插入一个结点
void Erase(LinkNode *pos);//删除某个结点
LinkNode *Find(DataType x);//查找结点并返回这个结点的地址
int Amount();//计算链表结点的数目
void Remove(DataType x);//查找某个结点并删除
void RemoveAll(DataType x);//删除链表中的所有x
private:
LinkNode* _head;//指向头结点
LinkNode* _tail;//指向尾结点
};
源文件实现部分;
#include "SingleLinkNode.h"
#include <assert.h>
#include <iostream>
using namespace std;
//结构体的构造函数
LinkNode::LinkNode(const DataType x)
:_data(x),_next(NULL)
{
};
SList::SList():_head(NULL),_tail(NULL){
}
SList::SList(const SList &s)//拷贝函数
:_head(NULL),_tail(NULL)
{
}
SList::~SList(){
Clear();
}
void SList::Uniqe(){//针对有序链表进行去重处理
assert(_head&&_head!=_tail);
LinkNode *left=_head;
LinkNode *right=_head->_next;
while(left!=_tail){
if (left->_data==right->_data)
{
LinkNode *pTemp=right;
left->_next=right->_next;
right=right->_next;
delete pTemp;
}
left=left->_next;
right=right->_next;
}
}
void SList::Merge(SList &s){
//如果_head为空
if (_head==NULL)
{
_head=s._head;
_tail=s._tail;
}
//如果s为空
if (s._head==NULL)
{
return;
}
//当两个链表都不为空时
LinkNode *pHead=_head;
if (pHead->_data<=s._head->_data)
{
pHead=pHead->_next;
}else
{
_head=s._head;
s._head=s._head->_next;
}
LinkNode *cur=_head;
while(1)
{
if (pHead->_data<=s._head->_data)
{
_head->_next=pHead;
_head=pHead->_next;
if (pHead==_tail)
{
_head->_next=s._head;
_tail=s._tail;
_tail->_next=cur;
break;;
}
pHead=pHead->_next;
}else
{
_head->_next=s._head;
_head=_head->_next;
if (s._head==s._tail)
{
_head->_next=pHead;
_tail->_next=cur;
break;
}
}
}
_head=cur;
}
void SList::Sort(){
}
int SList::Amount(){//计算节点的数目
int i=0;
if (_head==NULL)
{
return 0;
}
else
{
while(_head!=_tail){
i++;
_head=_head->_next;
}
}
return i;
}
void SList::PushBack(const DataType& x){
if (_head==NULL)
{
_head=new LinkNode(x);
_tail=_head;
_tail->_next=_head;
}else{
_tail=new LinkNode(x);
_tail=_tail->_next;
_tail->_next=_head;
}
}
void SList::Clear(){
LinkNode *begin=_head;
if (begin!=_tail)
{
_head=_head->_next;
delete begin;
begin=_head;
}
_head=NULL;
_tail=NULL;
}
void SList::PopBack()//尾删法
{
if(_head==NULL)
{
cout<<"The SList is empty!";
}
else if (_head==_tail)
{
delete _tail;
_head=NULL;
_tail=NULL;
}else
{
LinkNode *cur=_head;
while(cur!=_tail)
cur=cur->_next;
cur->_next=_head;
delete _tail;
_tail=cur;
}
}
void SList::PopFront(){
if (_head==NULL)
{
cout<<"The SList is the empty!"<<endl;
}
else
{
LinkNode *pHead=_head;
_tail->_next=pHead->_next;
_head=pHead->_next
delete pHead;
pHead=NULL;
}
}
//在pos节点后面插入新节点
void SList::Insert(LinkNode *pos,DataType x){
assert(pos);//如果为0(false)输出错误信息,并终止程序
if (pos==_tail)
{
PushBack(x);
}
else{
LinkNode *temp=new LinkNode(x);
temp->_next=pos->_next
pos->_next=temp;
}
}
void SList::Erase(LinkNode *pos){
assert(pos);
if(pos==_head)
{
PopFront();
}
else if (pos==_tail)
{
PopBack();
}else
{
LinkNode* prev=_head;
while(prev->_next!=pos){
prev=prev->_next;
}
prev->_next=pos->_next;
delete pos;
pos=NULL;
}
}
LinkNode *SList::Find(DataType x){
if (_head==NULL)
{
cout<<"The SList is empty";
return nullptr;
}
else {
LinkNode *temp=_head;
while(temp!=_head){
if (temp->_data==x)
{
return temp;
}
temp=temp->_next;
}
return NULL;
}
}
void SList::Remove(DataType x){
if (_head==NULL)
{
cout<<"This SList is the empty!";
}
else
{
LinkNode *pTemp=Find(x);
if(pTemp!=NULL){
Erase(pTemp);
}
}
}
void SList::RemoveAll(DataType x){
if (_head == NULL)
{
cout << "This SList is empty !" << endl;
return;
}
//如果链表不为空,设置left和right前后指针,从头至尾遍历一遍,delete节点的data为x的节点
LinkNode* left = _tail;
LinkNode* right = _head;
int count = Amount();
while (count--)
{
//当要删掉的节点是头节点时,需要注意头节点要指向它的下一个节点
//当要删掉的节点是尾节点时,需要注意尾节点要指向它的上一个节点
//当left和right指向同一块要删掉的节点时,将链表置空
if (right->_data == x)
{
if (_head == right)
{
_head = _head->_next;
}
if (_tail == right)
{
_tail =left;
}
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;
}
}
}