单向链表 (Singly linked list) 的C++实现

10 篇文章 0 订阅
6 篇文章 0 订阅

项目源代码

本文项目源代码可在此处下载(Visual Studio 2013项目文件):https://github.com/Voyager2718/Blog/tree/master/linked_list


简介

数组 (Array) 是一种很常用的顺序储存数据结构,理论上说,当我们新建一个数组的时候就是在内存中开辟了一段连续的内存空间,并返回一个指向这段内存空间第一个元素地址的指针。因此在初始化以后,因为内存管理的原因,数组不能增加或减少他的长度。所以当我们需要一段长度可变的数据结构的时候,我们就发明了链表。
链表 (Linked list) 是一种非顺序、非连续的数据结构。链表可以通过一个包含数据和指向其他节点指针的结构体(struct)或类(class)来实现。
这篇文章主要讨论的是单向链表的实现。
下面的表格对比了数组和单向链表的优劣势:

           单向链表  数组
实现复杂度   复杂     简单
查找复杂度   O(n)    O(1)
插入复杂度   O(1)    O(n)

单向链表的类定义

template<typename T>
class slist  {
private:
    struct _node{
        T element;
        _node *next;
    };
    _node *_pnode;
    int _size;
public:
    slist() :_size(0), _pnode(nullptr) {}
    ~slist(){ empty(); }
    void push_front(T);
    void push_back(T);
    T pop_front(void);
    T pop_back(void);
    T get(int);
    int size(void);
    T remove(int);
    void empty(void);
    bool isEmpty(void);
};

这里我定义了一个模板类,令我的单向链表可以处理各种数据类型。


往表头插入数据

template <typename T>
void slist<T>::push_front(T element){
    _node *node = new _node();
    node->element = element;
    if (_size == 0)
        node->next = nullptr;
    else
        node->next = _pnode;
    _pnode = node;
    _size++;
}

往表尾插入数据

template <typename T>
void slist<T>::push_back(T element){
    _node *node = new _node();
    node->element = element;
    if (_size == 0)
        _pnode = node;
    else{
        _node *tmp_node = _pnode;
        while (tmp_node->next != nullptr)
            tmp_node = tmp_node->next;
        tmp_node->next = node;
    }
    _size++;
}

删除第一个元素

template<typename T>
T slist<T>::pop_front(void){
    if (_size == 0)
        throw new IndexOutOfRangeException();
    T t = _pnode->element;
    _node *tmp_node = _pnode;
    _pnode = _pnode->next;
    delete (tmp_node);
    _size--;
    return t;
}

删除最后一个元素

template<typename T>
T slist<T>::pop_back(void){
    if (_size == 0)
        throw new IndexOutOfRangeException();
    T e;
    if (_size == 1){
        e = _pnode->element;
        delete(_pnode);
        _pnode = nullptr;
        _size--;
        return e;
    }
    _node *tmp_node = _pnode;
    while (tmp_node->next->next != nullptr)
        tmp_node = tmp_node->next;
    e = tmp_node->next->element;
    delete(tmp_node->next);
    tmp_node->next = nullptr;
    _size--;
    return e;
}

获得第n个元素(n∈[0,∞))

template <typename T>
T slist<T>::get(int index){
    if (index >= _size)
        throw new IndexOutOfRangeException();
    _node *tmp_node = _pnode;
    for (int i = 0; i < index; i++){
        tmp_node = tmp_node->next;
    }
    return tmp_node->element;
}

获得单向链表长度

template <typename T>
int slist<T>::size(){
    return _size;
}

删除第n个元素(n∈[0,∞))

template <typename T>
T slist<T>::remove(int index){
    if (index >= _size)
        throw new IndexOutOfRangeException();
    _node *tmp_node0 = _pnode, *tmp_node1 = nullptr;
    for (int i = 0; i < index - 1; i++){
        tmp_node0 = tmp_node0->next;
    }
    tmp_node1 = tmp_node0->next;
    tmp_node0->next = tmp_node0->next->next;
    T e = tmp_node1->element;
    delete(tmp_node1);
    _size--;
    return e;
}

清空链表

template <typename T>
void slist<T>::empty(){
    if (_size == 0)
        return;
    _node *tmp_node = _pnode;
    while (tmp_node->next != nullptr)
    {
        tmp_node = tmp_node->next;
        delete(_pnode);
        _pnode = tmp_node;
    }
    delete(_pnode);
    _pnode = nullptr;
    _size = 0;
}

确定链表是否为空

template <typename T>
bool slist<T>::isEmpty(){
    return _size == 0;
}

Exception 的定义

class Exception{
private:
    string message;
public:
    Exception(string message){
        this->message = string(message);
    }
    Exception(){}
    string getMessage(){
        return message;
    }
};
class IndexOutOfRangeException :public Exception{};

调用例子

int main(int argc, char *argv[]){
    slist<int> *list = new slist <int>();
    list->push_front(3);
    list->push_front(2);
    list->push_front(1);
    list->push_back(4);
    list->push_back(5);
    list->remove(2);
    for (int i = 0; i < list->size(); i++)
        cout << list->get(i) << endl;
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值