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

来源:互联网 发布:鹰卫浴淘宝 编辑:程序博客网 时间:2024/05/15 05:30

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;    //指向头节点的指针};
1 0