[C++] 链表 实现 源码 list link 关键词 : 模块 泛型编程

书 BOOK

书是这本书 :《C++ 程序设计原理与实践 第二版》
《Programming Principles and Practice Using C++ 》(Second Edition)[Bjarne Stroustrup] [1]

(中文) 第15章 容器和迭代器
Chapter 20: Containers and Iterators

参考网站 [1] 的那个网站,本书的配套官方网站,有包含全部书上示例代码的代码包,里面 第20章 那个文件夹CHAPTER 20,找到名字为Chapter 20.4.2.cpp的CPP源码文件,就是关于链表的简单源码,贴在下面了:

源码 CODE


//
// This is example code from Chapter 20.4.2 "Iteration" of
// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup
//

#include 

using namespace std;

//------------------------------------------------------------------------------

template struct Link {
    Link* prev;    // previous link
    Link* succ;    // successor (next) link
    Elem  val;     // the value
    Link(const Elem& v = Elem(), Link* p = 0, Link* s = 0) 
        : val(v), prev(p), succ(s) {}
};

//------------------------------------------------------------------------------

template class list {
    // representation and implementation details
public:
    class iterator;     // member type: iterator

    list() : first(new Link()), last(first) {}

    iterator begin();   // iterator to first element
    iterator end();     // iterator to one beyond last element

    iterator insert(iterator p, const Elem& v); // insert v into list after p
    iterator erase(iterator p);                 // remove p from the list

    void push_back(const Elem& v);  // insert v at end
    void push_front(const Elem& v); // insert v at front
    void pop_front();   // remove the first element
    void pop_back();    // remove the last element

    Elem& front();      // the first element
    Elem& back();       // the last element

    Link* first;
    Link* last;   // one-beyond-the-last link
};

//------------------------------------------------------------------------------

template class list::iterator {
    Link* curr;   // current node
public:
    iterator(Link* p) :curr(p) { }
    iterator& operator++() {curr = curr->succ; return *this; } // forward
    iterator& operator--() {curr = curr->prev; return *this; } // backwards
    Elem& operator*() { return curr->val; } // get value (dereference)

    friend bool operator==(const iterator& a, const iterator& b)
    {
        return a.curr==b.curr;
    }

    friend bool operator!=(const iterator& a, const iterator& b)
    {
        return a.curr!=b.curr;
    }
};

//------------------------------------------------------------------------------

template 
typename list::iterator list::begin()  // iterator to first element
{ 
    return iterator(first); 
}

//------------------------------------------------------------------------------

template 
typename list::iterator list::end() // iterator to one beyond last element
{ 
    return iterator(last); 
}

//------------------------------------------------------------------------------

template 
void list::push_front(const Elem& v) // insert v at front
{
    first = new Link(v,0,first);
}

//------------------------------------------------------------------------------

template
Iterator high(Iterator first, Iterator last)
// return an iterator to the element in [first,last) that has the highest value
{
    Iterator high = first;
    for (Iterator p = first; p!=last; ++p)
        if (*high<*p) high = p;
    return high;
}

//------------------------------------------------------------------------------

void f()
{
    list lst;
    int x;
    while (cin >> x) lst.push_front(x);

    list::iterator q = high(lst.begin(), lst.end());
    cout << "the highest value was " << *q << endl;

    list::iterator p = high(lst.begin(), lst.end());
    if (p==lst.end())    // did we reach the end?
        cout << "The list is empty";
    else
        cout << "the highest value is " << *p << endl;
}

//------------------------------------------------------------------------------

int main()
{
    f();
}

//------------------------------------------------------------------------------

运行 RUN

链表 C++ 实现 源码 Dev-C++ 5.11
12 243 2345 32 2345 656 756 878 -5 7
^Z
the highest value was 2345
the highest value is 2345

笔记 NOTE

  • 模块,泛型编程;
  • 迭代器,运算符重载;
  • 代码可读性极强;

空链表

list() : first(new Link()), last(first) {}

  • 链表的初始化,初始化出来一个空链表,空链表时first == last 为true
template
typename list::iterator list::begin()
{
    return iterator(first);
}

template
typename list::iterator list::end()
{
    return iterator(last);
}
  • begin() 返回 iterator(first)
  • end()返回 iterator(last)
  • end()也就是last指向的是最后一个Link的后一位one-beyond-the-last link【最重要的就是这里】
  • 因此才能用begin() == end()【也就是first == last】来判断链表是否为空,结果为true就是空,false就是非空;

解引用 就是 重载 星号运算符

template class list::iterator {
public:
...
    Elem& operator*() {return curr->val;}
...
};
  • 如果我有一个 iterator q,因为有上面这个重载函数Elem& operator*(),我用*q既可以得到q指向的linkval

push_front

template
void list::push_front(const Elem& v)
{
    first = new Link(v, 0, first);
}

  • 右边,调用了link的构造函数link(值,前一个link,后一个link), 就是在说,创建一个新的link,这个全新的link的值是v,这个全新的link后面跟着first;
  • 左边 first =
  • 整条语句就是在说,好了,现在这个全新的link成为了first;
  • 左、右两边都用了first,这是这个函数,这条语句最不容忽视的地方;

high()

本书第二版书上示例代码命名换成了更短的Iter的

template
Iter high(Iter first, Iter last)
{
    Iter high = first;
    for(Iter p = first; p != last; ++p)
        if(*high < *p) high = p;
    return high;
}
  • 其实,写成Iter 也好,还是 helloworld 都是可以的,这里只是和iterater做个区分,本质上都写成iterator完全可以,但是代码要有一致性,让人读起来会觉得命名一样的地方指的应该是同一种东西;
  • 编译器,自然懂怎么把 high() 里面的iter理解成list内置的iterator,自然懂去找iterator里面的星号重载函数 Elem& operator*()来处理*high以及*p;
  • iterator这个名字当然也是我们自己取的,这是为了和STL的标准保持一致,它当然也可以叫foobar;

使用模板,high()就更通用

void g()
{
    vector v {1,2,3,4,5};
    int* p = high(&v[0], &v[0]+v.size());
    cout << "the biggest int is  " << *p << endl;
}
the biggest int is  5

参考 REF

[1] http://www.stroustrup.com/Programming/
Supporting code: [Complete collection of code fragments for the 1st edition (revised)] (contains an automated build of FLTK for Windows)

你可能感兴趣的:([C++] 链表 实现 源码 list link 关键词 : 模块 泛型编程)