您的位置:首页 > 编程语言 > C语言/C++

【C++】c++实现线性表、链表

2015-10-02 23:22 453 查看

c++实现动态顺序表如下

typedef int DataType;
class SeqList
{
public:
//////////////类的基本成员函数定义/////////////////
SeqList()                     //构造函数(在类内定义)
:_elem(NULL)
, _capacity(0)
, _size(0)
{}
~SeqList()                  //析构函数
{
if (_elem)
{
delete[] _elem;
cout << "~SeqList()" << endl;
}
}
SeqList(const SeqList& s)    //拷贝构造函数
:_elem(new DataType[s._capacity])
, _capacity(s._capacity)
, _size(s._size)
{
memcpy(_elem, s._elem, _size*sizeof(DataType));
}
SeqList& operator= (const SeqList& s)  //赋值操作符重载
{
if (this != &s)  //防止自赋值
{
delete[] _elem;//释放原来空间
_elem = new DataType[s._capacity];//分配新空间
memcpy(_elem, s._elem, s._size*sizeof(DataType));
_size = s._size;
_capacity = s._capacity;
}
return *this;
}
//////////动态顺序表的基本操作实现///////////////
void _CheckCapacity();         //在类外定义
void _PrintSeqList();
void _PushBack(DataType data);
void _PopBack();
size_t Find(DataType data);
void Insert(size_t index,DataType data);
private:
DataType* _elem;   //指向当前空间的指针
size_t _capacity;     //当前空间容量大小
size_t _size;          //但钱空间有效数据的个数
};


类外定义成员函数如下:

void SeqList::_CheckCapacity()         //检查容量
{
if (_size == _capacity)
{
_capacity = _capacity * 2 + 5;//构造函数初始化时,_capacity为0
DataType* ret = (DataType*)malloc(_capacity*sizeof(DataType));
memcpy(ret, _elem, _size*sizeof(DataType));
delete[] _elem;
_elem = ret;
}
}
void SeqList::_PrintSeqList()
{
cout << "SeqList : ";
size_t index = 0;
for (; index < _size; index++)
{
cout << _elem[index] << " ";
}
cout << "NULL" << endl;
}
void SeqList::_PushBack(DataType data) //尾插数据
{
_CheckCapacity();
_elem[_size++] = data;
}
void SeqList::_PopBack()
{
if (_size == 0)
{
cout << "SeqList Is Empty" << endl;
return;
}
_size--;
}
size_t SeqList::Find(DataType data)    //查找数据,返回下标
{
size_t index = 0;
for (; index < _size; index++)
{
if (_elem[index] == data)
{
return index;
}
}
return _size+1;
}
void SeqList::Insert(size_t index, DataType data) //在下标index处插入一个数据
{
_CheckCapacity();
if (index > _size)
{
cout << "Invaid index" << endl;
return;
}
int i = _size-1;
for (; i >=(int)index; i--)  //注意此处i不能定义为size_t,且index要强转成int型,否则会成死循环
{                            //即使i一直减,但是无符号整型永远不会小于0,
_elem[i+1] = _elem[i];
}
_elem[index] = data;
_size++;
}


基本成员函数(如构造、拷贝构造、赋值操作符重载函数)还可以优化如下:

class SeqList
{
public:
//////////////类的基本成员函数定义/////////////////
SeqList(DataType* elem, size_t capacity, size_t size)   //构造函数
{
if (elem == NULL)
{
_elem = NULL;
_capacity = 0;
_size = 0;
}
else
{
_elem = new DataType[capacity];
memcpy(_elem, elem, size*sizeof(DataType));
_capacity = capacity;
_size = size;
}
}
~SeqList()                  //析构函数
{
if (_elem)
{
delete[] _elem;
cout << "~SeqList()" << endl;
}
}
void Swap(SeqList& s)
{
swap(_elem, s._elem);//自动调用系统实现的swap函数
swap(_capacity, s._capacity);
swap(_size, s._size);
}
SeqList(const SeqList& s)    //拷贝构造函数
:_elem(NULL)
, _capacity(0)
, _size(0)
{
SeqList tmp(s._elem, s._capacity, s._size);//通过构造函数进行初始化
Swap(tmp);  //将tmp与this的值交换,交换后this会指向原来tmp指向的空间
}
SeqList& operator= (const SeqList& s)  //赋值操作符重载
{
if (this != &s)  //防止自赋值
{
SeqList tmp(s._elem, s._capacity, s._size);
Swap(tmp);
}
return *this;
}
private:
DataType* _elem;   //指向当前空间的指针
size_t _capacity;     //当前空间容量大小
size_t _size;          //但钱空间有效数据的个数
};


解析:

SeqList tmp(s._elem, s._capacity, s._size);

Swap(tmp);

若已经存在的两个对象s1、s2;执行 s1 = s2 操作,则先创建一个临时对象tmp,将s2的值拷贝给tmp,再将tmp和s1的值进行交换,最后出了作用域就会释放这个临时对象tmp。如下图:



c++实现链表如下

单向循环链表

先了解:

关键字struct和class是同一等级的,

唯一区别是struct定义的成员默认是公有的,而class默认的成员是私有的

typedef int DataType;
struct LinkNode
{
LinkNode* _next;     //指向下一个节点的指针
DataType _data;  //当前节点的数据
LinkNode(const DataType data)    //构造函数
:_next(NULL)
,_data(data)
{}
};


class sList
{
public:
sList()                        //构造函数
:_head(NULL)
,_tail(NULL)
{}
sList(const sList& s)         //拷贝构造函数
:_head(NULL)
,_tail(NULL)
{
if(s._head == NULL)
{
return;
}
LinkNode* begin = s._head;
do
{
PushBack(begin->_data);  //this->PushBack(begin->_data);
begin = begin->_next;
} while (begin != s._head);
}
sList& operator= (const sList& s)   //赋值操作符重载
{
if (this != &s)
{
DistorysList();//先摧毁this指向的链表
LinkNode* begin = s._head;
do
{
PushBack(begin->_data);
begin = begin->_next;
} while (begin != s._head);
}
return *this;
}
~sList()                       //析构函数
{
Distory();
}
void DistorysList()            //撤销链表
{
while (_head)
{
PopBack();
}
}
void PushBack(DataType data)    //尾插
{
if (_head == NULL)
{
_head = new LinkNode(data);
_tail = _head;   //循环链表
}
else
{
_tail->_next = new LinkNode(data);
_tail = _tail->_next;
_tail->_next = _head;
}
}
void PopBack()                  //尾删
{
if (_head == NULL)//空链表
{
return;
}
if (_head == _tail)//一个节点
{
delete _head;
_head = NULL;
_tail = NULL;
}
else               //多个节点
{
LinkNode* prev = _head;
while (prev->_next != _tail)
{
prev = prev->_next;
}
delete _tail;
_tail = prev;
_tail->_next = _head;
}
}
void PrintsList()                  //打印链表
{
cout << "sList->";
if (_head != NULL)
{
LinkNode* begin = _head;
do
{
cout << begin->_data << "->";
begin = begin->_next;
}while (begin != _head);
}
cout << "NULL" << endl;
}
void Reverse()               //逆置链表
{
if (_head == NULL || _head == _tail)
{
return;
}
LinkNode* begin = _head->_next;
_head->_next = NULL;//摘下头节点
_tail->_next = NULL;//解开循环
_tail = _head;      //原来的头节点逆置后是尾节点
while (begin)
{
LinkNode* ret = begin;
begin = begin->_next;
ret->_next = _head;
_head = ret;
}
_tail->_next = _head;
}
private:
LinkNode* _head;   //指向头节点的指针
LinkNode* _tail;   //指向尾节点的指针
};


双向循环链表

typedef int DataType;
class DoubleNode
{
friend class DoubleList;        //友元函数
public:
DoubleNode(DataType data)       //构造函数
:_prev(NULL)
, _next(NULL)
, _data(data)
{}
private:
DoubleNode* _prev;
DoubleNode* _next;
DataType _data;
};


class DoubleList
{
public:
DoubleList()               //构造函数
:_head(NULL)
, _tail(NULL)
{}
DoubleList(const DoubleList& d) //拷贝构造函数
:_head(NULL)
, _tail(NULL)
{
if (d._head == NULL)
{
return;
}
DoubleNode* begin = d._head;
do
{
PushBack(begin->_data);
begin = begin->_next;
}while (begin != d._head);
}
DoubleList& operator= (const DoubleList& d)    //赋值操作符重载
{
if (this != &d)
{
Distory();
DoubleNode* begin = d._head;
do
{
PushBack(begin->_data);
begin = begin->_next;
} while (begin != d._head);
}
return *this;
}
~DoubleList()                       //析构函数
{
Distory();
}
void Distory()                   //摧毁链表
{
while (_head)
{
PopFront();
}
}
void PushBack(DataType data)     //尾插
{
if (_head == NULL)
{
_head = new DoubleNode(data);
_tail = _head;
}
else
{
DoubleNode* ret = new DoubleNode(data);
_tail->_next = ret;
ret->_prev = _tail;
_tail = ret;
_tail->_next = _head;   //成环
}
}
void PopFront()              //头删
{
if (_head == NULL)
{
cout << "DoubleList Is Empty" << endl;
}
else if (_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
DoubleNode* del = _head;
_head = _head->_next;
_head->_prev = NULL;
_tail->_next = _head;//更新尾指针
del->_next = NULL;
delete del;
}
}
void PrintDList()
{
cout << "DoubleList->";
if (_head != NULL)
{
DoubleNode* begin = _head;
do
{
cout << begin->_data << "->";
begin = begin->_next;
} while (begin != _head);
}
cout << "NULL" << endl;
}
private:
DoubleNode* _head;    //指向尾节点的指针
DoubleNode* _tail;    //指向头节点的指针
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: