List With Iterator(STL)

本文介绍了一个自定义实现的标准模板库(STL)列表容器,包括构造函数、迭代器操作及常用成员函数等,并通过示例展示了如何使用这些功能。

实现标准模板库中的功能

#include<iostream>
#include<string>
#include<cassert>
using namespace std;

template<class T>
class list {
 public:
  struct listelem;  // forward declarations
  //  也可将struct和iterator的定义直接放在前面
  class iterator;
  // 构造函数
  list() {
    h.ptr = t.ptr = NULL;
  }
  //  注意构造函数中,首先都应该将head和tail置为NULL
  //  n个值为c的链表
  list(size_t n_elements, const T& c) {
    h.ptr = t.ptr = NULL;
    for (size_t i = 0; i < n_elements; ++i) {
      //  此处用push_front和push_back都可以
      push_back(c);
    }
  }
  list(const list& x) {
    h.ptr = t.ptr = NULL;  //  重要
    list::iterator iter = x.begin();
    while (iter != NULL) {
      //  下面两句等价于push_back(*iter++);
      push_back(*iter);
      iter++;
    }
  }
  list(iterator b, iterator e) {
    h.ptr = t.ptr = NULL;
    while (b != e) {
      //  等价于push_back(*b++);
      push_back(*b);
      b++;
    }
  }
  ~list() {
    this->clear();
  }
  iterator begin() const {
    return h;
  }
  iterator end() const {
    //  返回的是最后一个迭代器的下一个
    iterator temp;
    return (temp.ptr == NULL ? iterator(0) : ++temp);
  }
  size_t size() {
    size_t count = 0;
    iterator temp = h;
    while (temp != end()) {
      temp++;
      count++;
    }
    return count;
  }
  void push_front(const T& c) {
    listelem* temp = new listelem(c, h, NULL);
    if (empty()) {  //  链表为空时或是if(h == NULL)
    // 或是if(h.ptr == NULL)
      h.ptr = t.ptr = temp;
    } else {   //  链表不为空时
      h->prev = temp;
      h.ptr = temp;
    }
  }
  void push_back(const T& c) {
    listelem* temp = new listelem(c, NULL, t);
    if (empty()) {
      h.ptr = t.ptr = temp;
    } else {
      t->next = temp;
      t.ptr = temp;
    }
  }
  void pop_front() {
    if (empty()) return;  //   链表为空的情况
    listelem* temp = h.ptr;
    if (h.ptr == t.ptr) {
      //  只有一个节点的情况
      h.ptr = NULL;
      t.ptr = NULL;
      delete temp;
    } else {
      h.ptr = h->next;
      h->prev = NULL;
      delete temp;
    }
  }
  void pop_back() {
    if (empty()) return;
    listelem* temp = t.ptr;
    if (h.ptr == t.ptr) {
      h.ptr = t.ptr = NULL;
      delete temp;
    } else {
      t.ptr = t->prev;
      t->next = NULL;
      delete temp;
    }
  }
  iterator insert(iterator position, const T& val) {
    listelem* p = position.ptr;
    if (p == end()) {  //  或者是p == NULL
      push_back(val);
      return t;
    } else if (p == begin()) {  //  或者是 p->prev == NULL
      push_front(val);
      return begin();
    } else {
      listelem* temp = new listelem(val, p, p->prev);
      temp->next->prev = temp;
      temp->prev->next = temp;
      return iterator(temp);
    }
  }
  iterator erase (iterator position) {
    listelem* temp = position.ptr;
    if (temp == NULL||empty()) return iterator(0);
    if (temp == h) {
      pop_front();
      return h;
    }
    temp->prev->next = temp->next;
    temp->next->prev = temp->prev;
    listelem* re = temp->next;
    delete temp;
    return iterator(re);
  }
  bool empty() const {
    return h.ptr == 0;
  }
  T& front() {
    return *h;
  }
  T& back() {
    return *t;
  }
  void clear() {
    while (h.ptr != 0) {
      pop_front();
    }
    h.ptr = t.ptr = NULL;
  }
  friend ostream& operator << (ostream& out, const list& x) {
    list<T>::iterator p = x.begin();
    out << "[";
    while (p != 0) {
      out << *p << " ";
      ++p;
    }
    out << "]";
    return out;
  }

  struct listelem {      // list cell
    T data;
    listelem *next, *prev;
    listelem(const T& s, listelem* n, listelem* p) {
      data = s;
      next = n;
      prev = p;
    }
  };

  class iterator {
   public:
    friend class list; 
    explicit iterator(listelem* p = 0) {
      ptr = p;
    }

    iterator(const iterator& other) {
      ptr = NULL;
      ptr = other.ptr;
    }
    iterator& operator ++ () {
      //  ++p;
      ptr = ptr->next;
      return *this;
    }
    iterator& operator -- () {
      ptr = ptr->prev;
      return *this;
    }
    iterator operator ++ (int) {
      //  p++;
      iterator temp = *this;
      ptr = ptr->next;
      return temp;
    }
    iterator operator -- (int) {
      iterator temp = *this;
      ptr = ptr->prev;
      return temp;
    }
    listelem* operator -> () {
      return ptr;
    }
    T& operator * () {
      return ptr->data;
    }
    operator listelem * () {
      return ptr;
    }  // conversion;
    private:
    listelem* ptr;  // current listelem or 0;
  };

  private:
  iterator h, t;  // head and tail
};

下面是main函数部分

int main() {
  list<int> li;
  cout << "test size" << endl;
  cout << li.size() << endl;
  cout << (li.empty() ? "empty" : "not empty") << endl;
  int n;  // n >= 3
  cout << "test push and pop" << endl;
  li.push_back(1);
  cout << li << endl;
  li.pop_back();
  cout << li << endl;
  li.push_front(1);
  cout << li << endl;
  li.pop_front();
  cout << li << endl;
  li.push_back(1);
  cout << li << endl;
  li.pop_front();
  cout << li << endl;
  li.push_front(1);
  cout << li << endl;
  li.pop_back();

  cin >> n;
  for (int i = 0; i < n; i++) {
    int tmp;
    cin >> tmp;
    li.push_back(tmp);
    li.push_front(tmp);
  }
  cout << li.size() << endl;
  cout << li << endl;
  li.pop_back();
  li.pop_front();
  li.pop_front();
  cout << li << endl;
  cout << "front : " << li.front() << endl;
  cout << "back : " << li.back() << endl;
  cout << (li.empty() ? "empty" : "not empty") << endl;

  cout << "test begin and end" << endl;
  list<int>::iterator it = li.begin();
  while (it != li.end()) {
    cout << it->data << " ";
    it++;
  }
  cout << endl;

  cout << "test insert and erase and ++ --" << endl;
  it = li.begin();
  cout << *(li.insert(it, 100)) << endl;
  it = li.end();
  cout << *(li.insert(it, 200)) << endl;
  cout << li << endl;
  it = li.begin();
  cout << *(li.erase(++it)) << endl;
  it = li.begin();
  it++;
  cout << *(li.erase(it)) << endl;
  cout << li << endl;
  it = li.begin();
  it++;
  it--;
  li.insert(it, 101);
  it = li.begin();
  ++it;
  --it;
  li.insert(it, 99);
  cout << li << endl;
  it = li.begin();
  *it = 90;

  cout << "test constructor" << endl;
  list<int> li2(5, 9);
  list<int> li3(li);
  it = li.begin();
  list<int>::iterator it2 = it;
  ++(++(++it2));
  list<int> li4(li.begin(), li.end());
  list<int> li5(it, it2);
  cout << li2 << endl;
  cout << li3 << endl;
  cout << li4 << endl;
  cout << li5 << endl;

  return 0;
}

input :
4
1 2 3 4
output:
test size
0
empty
test push and pop
[1 ]
[]
[1 ]
[]
[1 ]
[]
[1 ]
4
1
2
3
4
8
[4 3 2 1 1 2 3 4 ]
[2 1 1 2 3 ]
front : 2
back : 3
not empty
test begin and end
2 1 1 2 3
test insert and erase and ++ –
100
200
[100 2 1 1 2 3 200 ]
1
1
[100 1 2 3 200 ]
[99 101 100 1 2 3 200 ]
test constructor
[9 9 9 9 9 ]
[90 101 100 1 2 3 200 ]
[90 101 100 1 2 3 200 ]
[90 101 100 ]

乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
04-02
<think>好的,用户想了解Java标准模板库(STL)的使用教程和示例代码。首先,我需要确认Java是否有STL。因为STL是C++的标准模板库,而Java并没有直接对应的STL。不过,Java有类似的集合框架,也就是Java Collections Framework(JCF),可能用户混淆了这两个概念。 接下来,我要检查用户提供的引用内容。引用[1]提到Java集合框架的多态算法,引用[4]指出STL不依赖于面向对象,而JCF可能更面向对象。这说明需要向用户解释Java中的集合框架与C++ STL的区别,并提供相应的教程和示例。 用户的问题可能存在误解,所以首先需要澄清Java并没有STL,而是使用JCF。然后,需要介绍JCF的核心接口和常用类,如List、Set、Map等,并给出示例代码,比如ArrayList、HashSet、HashMap的使用。此外,引用[3]提到了迭代器的使用,可以结合QMutableListIterator的例子,说明Java中的迭代器用法,比如Iterator和增强for循环。 另外,引用[4]提到STL依赖模板,而JCF使用泛型,这点需要对比说明。例如,Java的泛型在编译时提供类型安全,而C++的模板在实例化时处理。 用户可能还希望了解如何实现类似STL中的算法,比如排序、查找等,可以引用Java的Collections类中的方法,如sort(),并展示示例代码。 需要确保回答结构清晰,分点讲解,并提供代码示例。同时,生成相关问题时要考虑用户可能的后续疑问,比如性能比较、泛型与模板的区别等。 最后,检查所有LaTeX格式是否正确,数学表达式用$...$,独立公式用$$...$$,但当前内容可能涉及较少数学公式,主要关注代码和文字说明。</think>Java本身并没有名为"标准模板库(STL)"的组件,这是C++特有的概念。但Java通过Collections Framework(集合框架)提供了类似STL的功能。以下是Java集合框架的核心知识点和示例: ### 一、Java集合框架核心结构 1. **接口体系** - `Collection`接口:所有集合类的根接口 - `List`有序集合:$O(1)$时间访问元素,如`ArrayList`[^1] - `Set`无序唯一集合:基于哈希表或树结构 - `Map`键值对映射:提供$O(1)$时间复杂度的查找 2. **泛型机制** 使用类型参数保证类型安全: ```java List<String> list = new ArrayList<>(); // 指定元素类型为String ``` ### 二、常用集合类示例 #### 1. ArrayList示例 ```java List<Integer> nums = new ArrayList<>(); nums.add(1); // 添加元素 nums.add(2); int first = nums.get(0); // 获取第一个元素 Collections.sort(nums); // 排序[^4] ``` #### 2. HashSet示例 ```java Set<String> names = new HashSet<>(); names.add("Alice"); names.add("Bob"); boolean exists = names.contains("Alice"); // 存在性检查 ``` #### 3. HashMap示例 ```java Map<String, Integer> scores = new HashMap<>(); scores.put("Alice", 95); scores.put("Bob", 88); int aliceScore = scores.get("Alice"); // 获取值 ``` ### 三、迭代器使用 ```java List<String> fruits = Arrays.asList("Apple", "Banana", "Orange"); Iterator<String> it = fruits.iterator(); while(it.hasNext()) { String fruit = it.next(); if(fruit.startsWith("A")) { it.remove(); // 类似QMutableListIterator的功能[^3] } } ``` ### 四、算法实现 Java通过`Collections`工具类提供通用算法: ```java List<Integer> numbers = new ArrayList<>(Arrays.asList(3,1,4,1,5)); Collections.sort(numbers); // 快速排序实现 Collections.shuffle(numbers); // 随机打乱 int max = Collections.max(numbers); // 查找最大值 ``` ### 五、与C++ STL的对比 | 特性 | Java集合框架 | C++ STL | |----------------|-------------------|------------------| | 实现基础 | 接口与泛型 | 模板 | | 多态性实现 | 接口继承 | 模板特化 | | 内存管理 | 自动垃圾回收 | 手动/智能指针 | | 算法组织方式 | Collections工具类 | <algorithm>头文件 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值