//

//  priority_queue.cpp

//  笔记

//

//  Created by fam on 15/3/16.

//

//

//---------------------------15/03/16----------------------------

//priority_queue

{

/*

priority_queue概述:

同正常队列一样,队尾进,队首出,不过不是先进后出,

有权值的概念,所以会自动排序(并不是全部排序,只要保证队

首值最大即可,权值最高的最先出队列,这里用的是堆来保证队首

的值

*/

template<class T,
class Sequence = vector<T>,

class Compare = less<typename Sequence::value_type> >

class priority_queue

{

public:

typedef typename Sequence::value_type value_type;

typedef typename Sequence::size_type size_type;

typedef typename Sequence::reference reference;

typedef typename Sequence::const_reference const_reference;

protected:

Sequence c;

Compare comp;

public:

priority_queue() : c(){};

//explict
可以有效防止隐式转化

explicit priority_queue(const Compare& x) : c(), comp(x){}

//下面都是直接调用heap算法来直接实现堆的操作

template<class InputIterator>

priority_queue(InputIterator first, InputIterator last,
const Compare& x)

:c(first,last), comp(x){ make_heap(c.begin(), c.end(), comp);}

template< class InputIterator>

priority_queue(InputIterator first, InputIterator last)

: c(first, last) {make_heap(c.begin(), c.end(), comp);}

bool empty() const {return c.empty();}

size_type size()
const {return c.size();}

const_reference top()
const {return c.front();}

void push(const value_type& x)

{

__STL_TRY

{

c.push_back(x);

push_heap(c.begin(), c.end(), comp);

}

__STL_UNWIND(c.clear());

}

void pop()

{

__STL_TRY

{

pop_heap(c.begin(), c.end(), comp);

c.pop_back();

}

__STL_UNWIND(c.clear());

}

/*

总结:

同queue
不提供迭代器。

不同queue,底层实现是用vector实现的(queue底层是deque实现的)

原因:queue每次进队列都在队尾,出队列都在队首,频繁地对头尾进行操作,

deque比vector性能好很多

priority_queue虽然也是队尾进,队首出,但是不可避免的是每次都要调整位置,

所以采用堆加vector是很好的选择(deque的随机访问是要比vector慢的),采用

堆每次插入,取出,都只用log(n)的时间,所以很好.

*/

};

}

//slist

{

/*

slist概述:

list是双向链表(double linked list),slist是单向链表

slist的迭代器属于单向的ForwardIterator,所以功能被限制了很多

但是耗用的空间小,操作更快.(我们大部分人最先接触的链表数据结构就是单向链表)

slist不提供push_back(),

*/

//__slist_node

struct __slist_node_base

{

__slist_node_base* next;

};

template <class T>

struct __slist_node :
public __slist_node_base

{

T data;

};

//添加一个节点(new_node)到prev_node之后

inline __slist_node_base* __slist_make_link(

__slist_node_base* prev_node,

__slist_node_base* new_node)

{

new_node->next = prev_node->next;

prev_node->next = new_node;

return new_node;

}

//通过循环判断node节点之后(包括node节点)一共有多少节点

inline size_t __slist_size(__slist_node_base* node)

{

size_t result =
;

; node = node->next)

++result;

return result;

}

//__slist_iterator

struct __slist_iterator_base

{

typedef size_t size_type;

typedef ptrdiff_t difference_type;

typedef forward_iterator_tag iterator_category;

//这里用基类创建一个节点

__slist_node_base* node;

__slist_iterator_base(__slist_node_base* x) :node(x){}

//相当于++操作

void incr() { node = node->next; }

//迭代器是否相等取决于他们的节点是否相等

bool operator==(const __slist_iterator_base& x)
const

{

return node == x.node;

}

bool operator!=(const __slist_iterator_base& x)
const{

return node != x.node;

}

};

//T: class Ref class& Ptr  class*

template<class T,
class Ref, class Ptr>

struct __slist_iterator :
public __slist_iterator_base

{

typedef __slist_iterator<T, T&, T*>     iterator;

typedef __slist_iterator<T,
const T&, const T*>     const_iterator;

typedef __slist_iterator<T, Ref, Ptr>   self;

typedef T   value_type;

typedef Ptr pointer;

typedef Ref reference;

//节点类型

typedef __slist_node<T> list_node;

__slist_iterator(list_node* x) : __slist_iterator_base(x) {}

__slist_iterator() : __slist_iterator_base(){}

__slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}

//node是__slist_node_base类型
需要强制转化

reference
operator*() const {return ((list_node*) node)->data;}

pointer
operator->() const {return &(operator*());}

self&
operator++()

{

incr();

return *this;

}

self
operator++(int)

{

self temp = *this;

incr();

return temp;

}

//并没有operator--操作

};

//class slist

template< class T,
class Alloc = allic>

class slist

{

public:

typedef T value_type;

typedef value_type* pointer;

typedef const value_type* const_pointer;

typedef value_type& reference;

typedef const value_type& const_reference;

typedef size_t size_type;

typedef ptrdiff_t difference_type;

typedef __slist_iterator<T, T&, T*> iterator;

typedef __slist_iterator<T,
const T&, const T*> const_iterator;

private:

typedef __slist_node<T> list_node;

typedef __slist_node_base list_node_base;

typedef __slist_iterator_base iterator_base;

typedef simple_alloc<list_node, Alloc> list_node_allocator;

//申请内存并调用构造函数

static list_node* create_node(const value_type& x)

{

list_node* node = list_node_allocator::allocate();

__STL_TRY

{

construct(&node->data, x);

node->next=;

}

__STL_UNWIND(list_node_allocator::deallocate(node));

return node;

}

static void destroy_node(list_node* node)

{

destroy(&node->data);

list_node_allocator::deallocate(node);

}

private:

list_node_base head;

public:

slist() { head.next =
; }

//clear()是循环删除所有节点

~slist() {clear();}

iterator begin() {return iterator((list_node*)head.next);}

//强制转化一个0为iterator类型表示end

//最开始的时候,head.next等于0
表示末尾;

iterator end() {);}

size_type size()
const {return __slist_size(head.next);}

bool empty() const {return head.next ==
;}

void swap(slist& L)

{

list_node_base* tmp =head.next;

head.next = L.head.next;

L.head.next = tmp;

}

public:

reference front() {return ((list_node*) head.next)->data;}

void push_front(const value_type& x)

{

__slist_make_link(&head, create_node(x));

}

void pop_front()

{

list_node* node = (list_node*) head.next;

head.next = node->next;

destroy_node(node);

}

};

/*

总结:

同deque一样,我还是不知道为什么在迭代器中会有self和iterator两个typedef

为什么要特地弄出两个基类?
这样的好处貌似是一个链表可以存放不同的数据类型,但是

并没有用啊。在使用slist<T>来声明定义变量时就确定了类型了。

别的没什么特别的技巧,就是一个很普通的list

*/

}

stl源码剖析 详细学习笔记priority_queue slist的更多相关文章

  1. stl源码剖析 详细学习笔记 hashtable

    //---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...

  2. stl源码剖析 详细学习笔记 set map

    // //  set map.cpp //  笔记 // //  Created by fam on 15/3/23. // // //---------------------------15/03 ...

  3. stl源码剖析 详细学习笔记 RB_tree (1)

    // //  RB_tree_STL.cpp //  笔记 // //  Created by fam on 15/3/21. // // #include "RB_tree_STL.h&q ...

  4. stl源码剖析 详细学习笔记heap

    // //  heap.cpp //  笔记 // //  Created by fam on 15/3/15. // // //---------------------------15/03/15 ...

  5. stl源码剖析 详细学习笔记 空间配置器

    //---------------------------15/04/05---------------------------- /* 空间配置器概述: 1:new操作包含两个阶段操作 1>调 ...

  6. stl源码剖析 详细学习笔记 算法(1)

    //---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...

  7. stl源码剖析 详细学习笔记 算法总览

    //****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...

  8. stl源码剖析 详细学习笔记 RB_tree (2)

    //---------------------------15/03/22---------------------------- //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多 ...

  9. stl源码剖析 详细学习笔记stack queue

    // //  stack.cpp //  笔记 // //  Created by fam on 15/3/15. // // //---------------------------15/03/1 ...

随机推荐

  1. oracle 忘记了scott用户的密码,该怎么修改

    sqlplus / as sysdba,进入sys用户下,alter user scott identified by 123456,改成自己需要的密码

  2. HDFS核心设计

    一.HDFS核心设计 数据块(block) 数据块是HDFS上最基本的存储单位 HDFS块默认大小为128M         对块进行抽象会带来的好处 一个小文件的大小可以大于网络中任意一个磁盘的容量 ...

  3. November 08th, 2017 Week 45th Wednesday

    Keep your face to the sunshine and you cannot see the shadow. 始终面朝阳光,我们就不会看到黑暗. I love sunshine, but ...

  4. SQLSERVER无排序生成序号

    实现方式:ROW_NUMBER() SELECT RowID=(ROW_NUMBER() OVER(ORDER BY(SELECT ))) FROM dbo.tbl_name 实现方式:IDENTIT ...

  5. Beta阶段第四次冲刺

    Beta阶段第四次冲刺 严格按照Git标准来,组员有上传Git的才有贡献分没有的为0 代码签入图 1.part1 -站立式会议照片 2.part2 -项目燃尽图 3.part3 -项目进展 1.正在进 ...

  6. FastDFS_v5.05+nginx+cache集群安装配置手册

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.FastDFS简单介绍 FastDFS是由淘宝的余庆先生所开发,是一个轻量级.高性能的开源分布式文件系统, ...

  7. BZOJ3578:GTY的人类基因组计划2(集合hash,STL)

    Description GTY召唤了n个人来做实验,GTY家的房子很大,有m个房间一开始所有人都在1号房间里,GTY会命令某人去某个房间等待做实验,或者命令一段区间的房间开始实验,实验会获得一些实验信 ...

  8. lucene查询语法简介

    为什么要介绍lucene:我们在ELK中搜索相关日志的时候,搜索语言需要遵循Lucene才可以匹配到需要的信息 什么是Lucene:Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件 ...

  9. 常见的CSS属性和值CascadingStyleSheets

    字体文本背景位置边框列表其他 CSS中修饰字体的属性 属    性 描    述 属  性  值 font-family 字体族科 任意字体族科名称都可以使用例如Times.serif等,而且多个族科 ...

  10. java读写properties配置文件方法

    1.Properties类 Properties类表示了一个持久的属性集.Properties可保存在流中或从流中加载,属性列表中的key和value必须是字符串. 虽然Properties类继承了j ...