單鏈表
相對於順序表,多了一個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();
}
這裏就實現了頭插,尾插,頭刪,尾刪,任意位置的插入刪除,並實現代碼的複用。