【C++】c++實現線性表、連結串列
阿新 • • 發佈:2019-01-04
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; //指向頭節點的指標
};