单链表和顺序表能够处理的问题都差不多,但是链表的优点在于能够节省空间,空间的利用率更高,程序执行的效率更快,链表的基本操作也是面试官喜欢考察的问题之一,链表是一种基本的数据结构,下面主要是利用c++来实现链表的基本功能。
//单向链表
#include <assert.h>
typedef int DataType;
class SListNode
{
friend class SList; //定义友元,类SList中可以用类SListNode的成员
public:
SListNode(DataType x) //构造函数
:Data(x)
, Next(NULL)
{ }
private:
DataType Data; //数据域
SListNode * Next; //指针域
};
class SList
{
public:
void pushBack(DataType x) //尾插节点
{
if (_head == NULL) //考虑没有节点的情况
{
_head = new SListNode(x); //new会自动调用构造函数
_tail = _head;
}
else
{
_tail->Next = new SListNode(x);
_tail = _tail->Next;
}
}
void popBack() //尾删节点
{
if (_head == _tail)
{
if (_head)
{
delete _head;
_head = _tail = NULL;
}
}
else
{
SListNode * tmp = _tail;
SListNode * cur = _head;
while (cur)
{
if (cur->Next->Next == NULL)
{
delete tmp;
_tail = cur;
_tail->Next = NULL;
}
cur = cur->Next;
}
}
}
void pushFront(DataType x) //头插节点
{
SListNode * tmp = new SListNode(x);
tmp->Next = _head;
_head = tmp;
}
void popFront() //头删节点
{
SListNode * tmp = _head;
if (tmp != NULL) //考虑无节点的情况
{
_head = _head->Next;
delete tmp;
}
}
void Insert(SListNode * pos, DataType x) //任意位置插入节点
{
assert(pos);
if (pos == _tail)
{
pushBack(x);
}
else
{
SListNode * tmp = new SListNode(x);
tmp->Next = pos->Next;
pos->Next = tmp;
}
}
SListNode * Find(DataType x) //查找
{
SListNode * cur = _head;
while (cur != NULL)
{
if (cur->Data == x)
{
return cur;
}
else
{
cur++;
}
}
if (cur == NULL)
{
cout << "查找不到!" << endl;
}
}
void Erase(SListNode * pos) //删除pos位置上的数据
{
assert(pos);
SListNode * cur = _head;
while (cur->Next != pos)
{
cur = cur->Next;
}
cur->Next = pos->Next;
delete pos;
}
void PrintSList() //格式输出
{
SListNode *cur = _head;
while (cur)
{
cout << cur->Data << " " ;
cur = cur->Next;
}
cout << endl;
}
void Clear() //释放全部节点
{
SListNode * cur = _head;
while (cur)
{
SListNode *tmp = cur;
cur = cur->Next;
delete tmp;
}
}
public:
SList() //无参构造函数
:_head(NULL)
, _tail(NULL)
{}
//深拷贝
SList(const SList & S) //拷贝构造函数
:_head(NULL)
, _tail(NULL)
{
SListNode * cur = S._head;
while (cur)
{
this->pushBack(cur->Data);
cur = cur->Next;
}
}
~SList() //析构函数
{
Clear();
}
//传统写法
SList& operator=(const SList & s) //赋值运算符重载
{
if (this != &s) //考虑自己给自己赋值的情况
{
this->Clear(); //需要释放全部的节点,delete只能释放一个节点
SListNode * cur = s._head;
while (cur)
{
this->pushBack(cur->Data);
cur = cur->Next;
}
}
}
现代写法
//SList & operator=(const SList & s)
//{
// swap(_head, s._head);
// swap(_tail, s._tail);
// return *this;
//}
private:
SListNode * _head; //指向头节点的指针
SListNode * _tail; //指向尾节点的指针
};
本文出自 “无心的执着” 博客,谢绝转载!