之前实现过c语言版本的顺序表和单向链表,现在实现c++版本的顺序表和双向链表:
再来看一下顺序表,单链表和双向链表的区别:
顺序表的c++实现:
#define _CRT_SECURE_NO_DEPRECATE 1
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
typedef int Datatype;
class SeqList
{
public:
//1开空间
//2放数据
SeqList()
:_pData(new Datatype[3])
,_size(0)
,_capacity(3)
{
}
//1开空间
//2放数据
//3给_size和_capacity
SeqList(const SeqList& d)
:_pData(new Datatype [d._capacity])
{
memmove(_pData,d._pData,sizeof(Datatype)*d._size);
_size = d._size;
_capacity = d._capacity;
}
//传统写法 1 判断是否自己给自己赋值 2 释放掉已有空间,开辟新的空间,移动数据,返回
//现代写法 1 判断是否自己给自己赋值 2 构造一个临时对象,交换内容,
SeqList& operator=(const SeqList& d)
{
if(_pData != d._pData)
{
delete[] _pData;
_pData = new Datatype [d._capacity];
memmove(_pData,d._pData,sizeof(d._pData)*d._size);
_size = d._size;
_capacity = d._capacity;
}
return *this;
}
~SeqList()
{
delete[] _pData;
_pData = NULL;
_size = 0;
_capacity = 0;
}
void CheckCapacity()
{
if(_size == _capacity)
{
//_pData = (Datatype*)realloc(_pData,_capacity*Datatype*2);
Datatype* tmp = new Datatype [_capacity*2];
assert(tmp);
for(size_t i=0; i<_size; i++)
{
tmp[i] = _pData[i];
}
swap(tmp,_pData);
delete[] tmp;
_capacity *= 2;
}
}
void PushBack(const Datatype & data)
{
//1判断是否为空
//2查满
//3插入数据
CheckCapacity();
_pData[_size++] = data;
}
void PopBack()
{
//1没有元素
//2有元素
assert(_size != 0);
_size--;
}
void Insert(size_t pos, const Datatype& data)//从0号地址开始插入
{
//1没有元素
//2在尾部插入
//3在中间插入
assert(pos <= _size);
size_t tmp = _size;
if(pos == _size)
{
PushBack(data);
}
else
{
CheckCapacity();
while(tmp>pos)
{
_pData[tmp] = _pData[tmp-1];
--tmp;
}
_pData[pos] = data;
_size++;
}
}
void Erase(size_t pos)
{
//1pos范围
//2在尾部擦出
//3在其他位置擦除
assert(pos<= _size);
if(pos == _size-1)
{
PopBack();
}
else
{
while(_size>pos)
{
_pData[pos] = _pData[pos+1];
pos++;
}
_size--;
}
}
void PrintSeqList()
{
for(size_t i=0; i<_size; i++)
{
cout<<_pData[i];
}
cout<<"\n";
}
int Find(const Datatype& data)
{
assert(_size > 0);
size_t i = 0;
while(i < _size)
{
if(_pData[i] == data)
{
return i;
}
i++;
}
return -1;
}
size_t Size()const
{
return _size;
}
size_t Capacity()const
{
return _capacity;
}
bool Empty()const
{
return !_size;
}
void Clear()
{
_size = 0;
}
void Resize(size_t size, const Datatype& data)
{
if(size <= _size)
{
_size = size;
}
else if(size > _size && size<=_capacity)
{
for(; _size<size; _size++)
{
_pData[_size] = data;
}
}
else //size > _capacity
{
//续加开空间
//初始化空间
_pData = (Datatype*)realloc(_pData,sizeof(Datatype)*size);
assert(_pData);
for(;_size<size;_size++)
{
_pData[_size] = data;
}
_capacity = size;
}
}
Datatype& operator[](size_t index)
{
assert(index<_size);
return _pData[index];
}
const Datatype& operator[](size_t index)const
{
assert(index<_size);
return _pData[index];
}
Datatype& Front()
{
assert(_size>0);
return _pData[0];
}
const Datatype& Front()const
{
assert(_size>0);
return _pData[0];
}
Datatype& Back()
{
assert(_size>0);
return _pData[_size-1];
}
const Datatype& Back()const
{
assert(_size>0);
return _pData[_size-1];
}
private:
Datatype* _pData;
size_t _size;
size_t _capacity;
};
void test1()
{
SeqList d1;
d1.PushBack(1);
d1.PushBack(2);
d1.PushBack(3);
d1.Insert(0,0);
d1.PrintSeqList();
d1.Erase(3);
d1.PrintSeqList();
d1[0] = 4;
d1.PrintSeqList();
}
void test2()
{
SeqList d1;
d1.PushBack(1);
d1.PushBack(2);
d1.PushBack(3);
d1.PushBack(4);
d1.PrintSeqList();
SeqList d3;
d3 = d1;
d3.PrintSeqList();
SeqList d2(d1);
d1.PopBack();
d1.PopBack();
d1.PopBack();
d1.PopBack();
d1.PrintSeqList();
d2.Resize(10,0);
d2.PrintSeqList();
}
int main()
{
test1();
system("pause");
return 0;
}
c++版本双向链表:
#define _CRT_SECURE_NO_DEPRECATE 1
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
typedef int DataType;
struct Node
{
Node(const DataType& data)
: _pNext(NULL)
, _pPre(NULL)
, _data(data)
{}
Node* _pNext;
Node* _pPre;
DataType _data;
};
class List
{
public:
List()
:_phead(NULL)
{
}
List(size_t n, DataType data)//构造那个数据为data的节点
{
//n==0
//n==1
//n>1
if(n == 0)
{
return ;
}
else if(n == 1)
{
_phead = BuyNode(data);
}
else
{
_phead = BuyNode(data);
Node* tmp = _phead;
while(n--)//--n
{
tmp->_pNext = BuyNode(data);
tmp->_pNext->_pPre = tmp;
tmp = tmp->_pNext;
}
}
}
//链表后插
void PushBack(const DataType& data)
{
//没有节点
//一个节点
//多个节点
if(_phead == NULL)
{
_phead = BuyNode(data);
}
else if(_phead->_pNext == NULL)
{
_phead->_pNext = BuyNode(data);
_phead->_pNext->_pPre = _phead;
}
else
{
Node* tmp = _phead;
while(tmp->_pNext != NULL)
{
tmp = tmp->_pNext;
}
tmp->_pNext = BuyNode(data);
tmp->_pNext->_pPre = tmp;
}
}
//链表尾删
void PopBack()
{
//没有节点
//1个节点
//很多节点
if(_phead == NULL)
{
return;
}
else if (_phead->_pNext == NULL)
{
delete _phead;
_phead = NULL;
}
else
{
Node* tmp = _phead;
while(tmp->_pNext != NULL)
{
tmp = tmp->_pNext;
}
tmp->_pPre->_pNext = NULL; //尾节点的前一个节点的pnetx制空
delete tmp; //删除尾节点
tmp = NULL;
}
}
void PushFront(const DataType& data)//头部插入
{
//链表为空
//链表不为空
if(_phead == NULL)
{
_phead = BuyNode(data);
}
else
{
//头部插入
Node* tmp = _phead;
Node* tmpNode = BuyNode(data);
tmp->_pPre = tmpNode;
tmpNode->_pNext = tmp;
_phead = _phead->_pPre;
}
}
void PopFront()
{
if(_phead == NULL)
{
return ;
}
else if(_phead->_pNext == NULL)
{
delete _phead;
_phead = NULL;
}
else
{
Node* tmp = _phead; //保存头节点
_phead = _phead->_pNext; //头指针向后走一步
_phead->_pPre = NULL; //置空向前的指针
delete tmp; //删除原始表头
}
}
Node* Find(const DataType& data)
{
//空链表
//非空链表
if(_phead == NULL)
{
return NULL;
}
else
{
Node* tmp = _phead;
while (tmp)
{
if(tmp->_data == data)
{
return tmp;
}
tmp = tmp->_pNext;
}
}
return NULL;
}
//在指定位置前面插入一个节点
void Insert(Node* pos, const DataType& data)
{
//判断pos和链表是否为空
//是否在第一个元素的前面插入
//其他位置插入
assert(pos);
if(pos == _phead)
{
PushFront(data);
}
else
{
//买节点
//保存pos的pre指针
//连接
Node* NewNode = BuyNode(data);
Node* tmppre = pos->_pPre;
//跟pos链接
NewNode->_pNext = pos;
pos->_pPre = NewNode;
//跟pos之前节点连接
tmppre->_pNext = NewNode;
NewNode->_pPre = tmppre;
}
}
//擦出指定节点
void Erase(Node* pos)
{
//pos和链表不能为空
//擦出头节点
//擦出尾节点
//擦出其他节点
assert(pos && _phead);
if(pos == _phead)
{
PopFront();
}
else if (pos->_pNext == NULL)
{
PopBack();
}
else
{
pos->_pPre->_pNext = pos->_pNext;
pos->_pNext->_pPre = pos->_pPre;
delete pos;
pos = NULL;
}
}
size_t Size()
{
size_t count = 0;
Node* tmp = _phead;
while(tmp)
{
count++;
tmp = tmp->_pNext;
}
return count;
}
bool Empty()const
{
return !_phead;
}
List(const List& d)//拷贝构造
{
//建立头节点
//之后的一个个pushback
Node* tmp = d._phead;
_phead = BuyNode(d._phead->_data) ;
tmp = tmp->_pNext;
while (tmp)
{
PushBack(tmp->_data);
tmp = tmp->_pNext;
}
}
void swap(Node** p1, Node** p2)
{
Node* tmp =* p1;
*p1 = *p2;
*p2 = tmp;
}
List& operator=(const List& d)
{
//返回与临时变量交换的空间
if(_phead != d._phead)
{
List tmp(d);
swap(&_phead,&(tmp._phead));
}
return *this;
}
~List()
{
//空
//不空
if(_phead == NULL)
{
return ;
}
Node* tmpbef = _phead;
Node* tmpaft = _phead->_pNext;
while (tmpbef)
{
delete tmpbef;
tmpbef = tmpaft;
if(tmpbef != NULL)
{
tmpaft = tmpaft->_pNext;
}
}
}
void PrintList()
{
//双向打印
if(_phead != NULL)
{
Node* tmp = _phead;
Node* tmpbef ;
while (tmp)
{
cout<<tmp->_data;
tmpbef = tmp;
tmp = tmp->_pNext;
}
cout<<"\n";
while (tmpbef)
{
cout<<tmpbef->_data;
tmpbef = tmpbef->_pPre;
}
}
cout<<"\n";
}
private:
Node* BuyNode(const DataType& data)
{
return new Node(data);
}
private:
Node* _phead;
};
void test1()
{
//测试push和pop
List d1;
d1.PushBack(1);
d1.PushBack(2);
d1.PushBack(3);
d1.PushBack(4);
d1.PushBack(5);
d1.PrintList();
d1.PopBack();
d1.PopBack();
d1.PopBack();
d1.PopBack();
d1.PopBack();
d1.PrintList();
d1.PushFront(6);
d1.PushFront(7);
d1.PushFront(8);
d1.PushFront(9);
d1.PushFront(10);
d1.PrintList();
d1.PopFront();
d1.PopFront();
d1.PopFront();
d1.PopFront();
d1.PopFront();
d1.PrintList();
}
void test2()
{
//测试构造函数 拷贝构造 /* 赋值*/ 析构
List d1;
d1.PushBack(1);
d1.PushBack(2);
d1.PushBack(3);
d1.PushBack(4);
d1.PushBack(5);
d1.PrintList();
List d2(d1);
d2.PrintList();
List d3 ;
d3.PushFront(6);
d3.PushFront(7);
d3.PushFront(8);
d3 = d2;
d3.PrintList();
}
void test3()
{
//初始化n个节点 Find insert earse Size Empty
List d1(3,5);
//d1.PrintList();
List d2;
d2.PushBack(1);
d2.PushBack(2);
d2.PushBack(3);
d2.PushBack(4);
d2.PushBack(5);
d2.PrintList();
Node* pos = d2.Find(1);
d2.Insert(pos,0);
d2.PrintList();
d2.Erase(pos);
d2.PrintList();
cout<<d2.Empty()<<endl;
cout<<d2.Size()<<endl;
}
int main()
{
test2();
system("pause");
return 0;
}