【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; //指向头节点的指针 };
相关文章推荐
- 【C++知识点】可重载与不可重载的操作符
- 项目26.3 本月有几天?
- c++ primer 练习5.19
- 《C++primer(第五版)》学习之路-第十五章:面向对象程序设计
- C语言: 函数调用的开销
- 值得推荐的C/C++框架和库
- c/c++ 2048 120行左右~
- c++ primer 练习5.17
- effective c++ 条款2 尽量以const enum inline代替#define
- 金融系统中PBOC/EMV的TLV的算法实现(含C++/C#)
- c++ primer 练习5.14
- c++抽象工厂模式
- 浅析C/C++中的switch/case陷阱
- effective c++ 以对象管理资源
- C++迭代器 iterator
- 项目26.2分段函数求值(switch语句)
- C++等级考试选择篇(二)
- 关于StdAfx.h和StdAfx.cpp
- 将链串s中的所有子串"abc"删除
- c prime plus第十四章练习题