• C++自己实现list


     C++自己实现list

      前两个博客发表了自己写的stack(栈)和queue(队列),感觉比较简单,今天想试着实现list,结果发现,不是那么容易,感觉自己对STL的底层不是很了解,

    真要自己实现还真的很难,看STL的源代码,那个晕啊...那代码也写得太难理解了,当然跟我不了解有关,但我相信,在将来的某一天我会懂的,你看我的代码也会懂的。

      话说:STL中的list的内部结构就是一个双向链表,这个东东以前还真没有玩过,就凭他用的是双向链表我就不想用他,指针太多,耗资源,当然存在就有他的价值,

    他能快速访问其中的元素。 废话总该少说,代码就该多些。

      有那么一点高兴的是实现双向链表的翻转,其他的没什么了,list还没有实现,由于现在能力有限,新的版本一定会发布的,你就将就着看吧!

    源码
    #include <iostream>
    usingnamespace std;

    template
    <typename T>
    class list
    {
    public :
    list()
    {
    initialize();
    }

    list(
    int count)
    {
    initialize();
    if(count>0)
    {
    for(int i=0;i<count;i++)
    {
    push_front(
    0);
    }
    }
    }

    list(
    int count,T data)
    {
    initialize();
    if(count>0)
    {
    for(int i=0;i<count;i++)
    {
    push_front(data);
    }
    }
    }

    //显示最后一个节点
    T& back()
    {
    checkEmpty();
    return cur->data;
    }

    T
    & back() const
    {
    return back();
    }

    //显示第一个节点
    T& front()
    {
    checkEmpty();
    return head->next->data;
    }

    T
    & front() const
    {
    return front();
    }

    //弹出最后一个节点
    void pop_back()
    {
    checkEmpty();
    cur
    =cur->prev;
    delete cur
    ->next;
    cur
    ->next=NULL;
    --len;
    }

    //弹出第一个节点
    void pop_front()
    {
    checkEmpty();
    node
    * tmp=head->next;
    head
    ->next=tmp->next;
    tmp
    ->prev=head;
    delete tmp;
    --len;
    }

    //前插节点
    void push_front(const T& t)
    {
    node
    * newNode=new node(t);
    head
    ->next=newNode;
    newNode
    ->prev=head;
    ++len;
    }

    //后插节点
    void push_back(const T& t)
    {
    node
    * newNode=new node(t);
    newNode
    ->prev=cur;
    cur
    ->next=newNode;
    cur
    =newNode;
    ++len;
    }

    //删除所有值为t的节点
    void remove(const T& t)
    {
    checkEmpty();
    node
    * tmp=head->next;
    for(int i=0;i<len;i++)
    {
    if(tmp->data!=t)
    {
    tmp
    =tmp->next;
    continue;
    }

    if(tmp->next==NULL)//删除最后一个节点
    {
    cur
    =tmp->prev; //将当前节点指向最后一个节点的前一个节点
    cur->next=NULL;//由于保持当前节点指向最后一个节点,他的下一个节点当然为空
    }else//删除中间节点
    {
    tmp
    ->prev->next=tmp->next; //要删除节点的前一个节点的next指针指向要删除节点的下一个节点
    tmp->next->prev=tmp->prev; //要删除节点的下一个节点的prev指针指向要删除节点的前一个节点
    }
    --len;
    node
    * t=tmp->next;
    delete tmp;
    tmp
    =t;
    }
    }


    //反转链表
    //每次都修改当前节点的前后节点指针
    //最后一个节点的下一个指针指向前一个节点
    void reverse()
    {
    checkEmpty();

    node
    * prev = head;// 上一个节点
    node* pcur = head->next;//当前节点
    node* next;
    while (pcur !=NULL)
    {
    if(!pcur->next)
    {
    pcur
    ->next=prev;//最后一个节点的下一个节点指向前一个节点
    break;
    }

    next
    = pcur->next; //下一个节点

    pcur
    ->next=prev; //修改当前节点的下一个节点
    pcur->prev=next; //修改当前及诶单的上一个节点

    prev
    =pcur; //将当前节点设为上一个节点
    pcur=next; //将下一个节点设为当前节点
    }
    cur
    =head->next; //末节点指向头节点
    head->next=pcur; //头指针指向当前节点,也就是指向翻转之前的末节点
    }

    //排序
    //节点之间直接交换数据,而没有用修改指针指向
    void sort()
    {
    if(empty())
    {
    return;
    }
    node
    *p,*t;
    p
    =head->next;
    T d;
    while(p!=NULL)
    {
    t
    =p;
    while(t!=NULL)
    {
    if(p->data>t->data)
    {
    d
    =p->data;
    p
    ->data=t->data;
    t
    ->data=d;
    }
    t
    =t->next;
    }
    p
    =p->next;
    }
    }


    //链表元素个数
    int size()
    {
    return len;
    }

    void resize(int count)
    {
    resize(count,
    0);
    }

    //重新设置元素
    void resize(int count,T t)
    {
    if(count<0)
    {
    thrownew exception("元素的个数不能小于0!");
    }
    clear();
    //内存是必须释放的
    while(count--)
    {
    push_front(t);
    }
    }

    //清空集合
    void clear()
    {
    if(empty())
    {
    return;
    }
    node
    *tmp=head;
    node
    *t=tmp->next;
    while(t!=NULL)
    {
    tmp
    =t;
    t
    =t->next;
    delete tmp;
    }
    tmp
    =NULL;
    t
    =NULL;

    cur
    =head;//当前节点指向头指针
    }


    //链表是否为空
    bool empty() const
    {
    return len==0;
    }

    //判断链表是否为空
    void checkEmpty()
    {
    if(empty())
    {
    thrownew exception("集合中没有元素!");
    }
    }


    private :
    typedef
    struct node1
    {
    node1
    *prev,*next;
    T data;
    node1(T t):data(t),prev(NULL),next(NULL){}
    }node;

    node
    * head;//头节点
    node* cur; //当前节点,指向末节点
    int len; //节点个数

    void initialize()
    {
    cur
    =head=new node(-1);
    len
    =0;
    }
    };

    作者:陈太汉

  • 相关阅读:
    Js通用验证
    C#实现马尔科夫模型例子
    C# 生成pdf文件客户端下载
    Js跨一级域名同步cookie
    C#数据库连接池 MySql SqlServer
    关于Oracle row_number() over()的简单使用
    开发中mybatis的一些常见问题记录
    Java通过图片url地址获取图片base64位字符串的两种方式
    基于apache httpclient的常用接口调用方法
    通过jcrop和canvas的画布功能完成对图片的截图功能与视频的截图功能实现
  • 原文地址:https://www.cnblogs.com/hlxs/p/2113178.html
Copyright © 2020-2023  润新知