单链表
相对于顺序表,多了一个next指针,用来连接数据,构成链式结构
下面是代码
#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
struct SListNode
{
SListNode* _next;
DataType _data;
SListNode(DataType x)
:_data(x)
,_next(NULL)
{}
};
class SList
{
typedef SListNode Node;
public:
SList()
:_head(NULL)
,_tail(NULL)
{}
SList(const SList& s)
//单链表这里使用深拷贝的方法解决深浅拷贝的问题
:_head(NULL)
,_tail(NULL)
{
//直接用pushback来进行节点的创建,实现拷贝
Copy(s);
}
//s1 = s2;
//先把s1析构,再拷贝
SList& operator=(const SList& s)
{
if(this!=&s)
{
Destroy();
Copy(s);
}
return *this;
}
~SList()
{
Destroy();
}
void PushBack(DataType x)
{
if(_head==NULL)
{
_head = _tail = new Node(x);
}
else
{
Node*tmp = new Node(x);
_tail->_next = tmp;
_tail = tmp;
}
}
void PopBack()
{
if(_head==NULL)
{
return ;
}
else if(_head == _tail)//一个节点
{
Node*del = _head;
delete del;
del = NULL;
_head = _tail = NULL;
}
else
{
Node*prev = _head;
while(prev->_next!=_tail)
{
prev = prev->_next;
}
Node *del = _tail;
prev->_next = del->_next;
delete del;
del = NULL;
_tail = prev;
}
}
void PushFront(DataType x)
{
if(_head==NULL)
{
_head = _tail = new Node(x);
}
else
{
Insert(_head,x);
// Node*tmp = new Node(x);
// tmp ->_next = _head;
// _head = tmp;
}
}
void PopFront()
{
if(_head==NULL)
return;
else
{
Node*del = _head;
_head = del->_next;
delete del;
del = NULL;
}
}
// 插入一个节点在pos的前面
void Insert(Node* pos, DataType x)
{
assert(pos);
if(pos==_head)
{
Node*cur = new Node(x);
cur->_next = pos;
_head = cur;
//PushFront(x);
}
else
{
Node*tmp = new Node(x);
Node*prev = _head;
while(prev->_next!=pos)
{
prev = prev->_next;
}
tmp->_next = pos;
prev->_next = tmp;
}
}
void Erase(Node* pos)
{
assert(pos);
if(pos==_head)//就直接处理掉了_head==_tail的情况
{
Node*del = _head;
_head = del->_next;
delete del;
del = NULL;
}
else
if(pos==_tail)//走到这里,肯定是有一个以上结点
{
Node*prev = _head;
Node*del = _tail;
while(prev->_next!=pos)
{
prev = prev->_next;
}
prev->_next = del->_next;
delete del;
del = NULL;
_tail = prev;
}
// if(pos==_head)
// {
// PopFront();
// }
// if(pos==_tail)
// {
// PopBack();
// }
else
{
Node*del = pos;
Node*prev = _head;
while(prev->_next!=pos)
{
prev = prev->_next;
}
prev->_next = del->_next;
delete del;
del = NULL;
}
}
Node*Find(DataType x)
{
Node*cur = _head;
while(cur)
{
if(cur->_data==x)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}
void Print()
{
Node*cur = _head;
while(cur)
{
cout<<cur->_data<<" ";
cur = cur->_next;
}
cout<<endl;
}
protected:
void Destroy()
{
if(_head==NULL)
{
return;
}
else
{
Node*cur = _head;
while(cur)
{
Node*del = cur;//这里注意要用一个临时的变量将cur保存,否则析构后就找不到他了
cur = cur->_next;
delete del;
}
_head = _tail = NULL;
}
}
void Copy(const SList&s)//谁调用就拷贝谁
{
Node *cur = s._head;
while(cur)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
private:
Node* _head;
Node* _tail;
};
void SListTest()
{
SList s1;
s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(4);
SList s2(s1);
SList s3;
s3.PushBack(5);
s3.PushBack(6);
s3.PushBack(7);
s3.PushBack(5);
s3.Print();
s2 = s3;
s1.Print();
s2.Print();
}
void SListTest1()
{
SList s1;
/*s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(4);
s1.PushBack(5);*/
s1.PushFront(2);
s1.PushFront(4);
s1.PushFront(5);
SListNode*ret = s1.Find(5);
cout<<ret->_data<<endl;
//s1.Insert(ret,0);
s1.Erase(ret);
// s1.PopBack();
// s1.PopBack();
// s1.PopBack();
// s1.PopBack();
// s1.PopBack();
// s1.PopFront();
// s1.PopFront();
// s1.PopFront();
// s1.PopFront();
// s1.PopFront();
s1.Print();
}
这里就实现了头插,尾插,头删,尾删,任意位置的插入删除,并实现代码的复用。