C++ 使用迭代器类将x插入到排序列表*中,而不使用*
我对如何完成这个功能感到困惑C++ 使用迭代器类将x插入到排序列表*中,而不使用*,c++,list,doubly-linked-list,C++,List,Doubly Linked List,我对如何完成这个功能感到困惑 按顺序(常量对象和x)作废原始插入 目标是在不使用迭代器类的情况下将x插入到排序列表中,假设列表为空或排序正确。 这让我感到困惑,因为程序本身使用迭代器类,但项目要求我们在不使用迭代器类的情况下执行函数。有人知道如何按顺序插入的功能吗?我需要帮助。我很感激 #ifndef LIST_H #define LIST_H #include <algorithm> using namespace std; template<typename Obje
按顺序(常量对象和x)作废原始插入 目标是在不使用迭代器类的情况下将x插入到排序列表中,假设列表为空或排序正确。 这让我感到困惑,因为程序本身使用迭代器类,但项目要求我们在不使用迭代器类的情况下执行函数。有人知道如何按顺序插入的功能吗?我需要帮助。我很感激
#ifndef LIST_H
#define LIST_H
#include <algorithm>
using namespace std;
template<typename Object>
class List {
private:
// The basic doubly linked list node.
// Nested inside of List, can be public
// because the Node is itself private
struct Node {
Object data;
Node *prev;
Node *next;
Node(const Object &d = Object{}, Node *p = nullptr, Node *n = nullptr)
: data{d}, prev{p}, next{n} {}
Node(Object &&d, Node *p = nullptr, Node *n = nullptr)
: data{std::move(d)}, prev{p}, next{n} {}
};
public:
class const_iterator {
public:
// Public constructor for const_iterator.
const_iterator() : current{nullptr} {}
// Return the object stored at the current position.
// For const_iterator, this is an accessor with a
// const reference return type.
const Object &operator*() const { return retrieve(); }
const_iterator &operator++() {
current = current->next;
return *this;
}
const_iterator operator++(int) {
const_iterator old = *this;
++(*this);
return old;
}
const_iterator &operator--() {
current = current->prev;
return *this;
}
const_iterator operator--(int) {
const_iterator old = *this;
--(*this);
return old;
}
bool operator==(const const_iterator &rhs) const { return current == rhs.current; }
bool operator!=(const const_iterator &rhs) const { return !(*this == rhs); }
protected:
Node *current;
// Protected helper in const_iterator that returns the object
// stored at the current position. Can be called by all
// three versions of operator* without any type conversions.
Object &retrieve() const { return current->data; }
// Protected constructor for const_iterator.
// Expects a pointer that represents the current position.
const_iterator(Node *p) : current{p} {}
friend class List<Object>;
};
class iterator : public const_iterator {
public:
// Public constructor for iterator.
// Calls the base-class constructor.
// Must be provided because the private constructor
// is written; otherwise zero-parameter constructor
// would be disabled.
iterator() {}
Object &operator*() { return const_iterator::retrieve(); }
// Return the object stored at the current position.
// For iterator, there is an accessor with a
// const reference return type and a mutator with
// a reference return type. The accessor is shown first.
const Object &operator*() const { return const_iterator::operator*(); }
iterator &operator++() {
this->current = this->current->next;
return *this;
}
iterator operator++(int) {
iterator old = *this;
++(*this);
return old;
}
iterator &operator--() {
this->current = this->current->prev;
return *this;
}
iterator operator--(int) {
iterator old = *this;
--(*this);
return old;
}
protected:
// Protected constructor for iterator.
// Expects the current position.
iterator(Node *p) : const_iterator{p} {}
friend class List<Object>;
};
public:
List() { init(); }
~List() {
// Place your code here.
clear( );
delete head;
delete tail;
}
List(const List &rhs) {
init();
for (auto &x : rhs)
push_back(x);
}
List &operator=(const List &rhs) {
List copy = rhs;
std::swap(*this, copy);
return *this;
}
List(List &&rhs) : theSize{rhs.theSize}, head{rhs.head}, tail{rhs.tail} {
rhs.theSize = 0;
rhs.head = nullptr;
rhs.tail = nullptr;
}
List &operator=(List &&rhs) {
std::swap(theSize, rhs.theSize);
std::swap(head, rhs.head);
std::swap(tail, rhs.tail);
return *this;
}
// Return iterator representing beginning of list.
// Mutator version is first, then accessor version.
iterator begin() { return iterator(head->next); }
const_iterator begin() const { return const_iterator(head->next); }
// Return iterator representing endmarker of list.
// Mutator version is first, then accessor version.
iterator end() { return iterator(tail); }
const_iterator end() const { return const_iterator(tail); }
// Return number of elements currently in the list.
int size() const { return theSize; }
// Return true if the list is empty, false otherwise.
bool empty() const { return size() == 0; }
void clear() {
while (!empty())
pop_front();
}
// front, back, push_front, push_back, pop_front, and pop_back
// are the basic double-ended queue operations.
Object &front() { return *begin(); }
Object &raw_front() {
// Return the element at the front of the list *without* using the iterator classes
// (You may assume the list is not empty)
// (Yes, this is bad code. I just needed something that will allow the stub to compile.)
return head ;
}
const Object &front() const { return *begin(); }
Object &back() { return *--end(); }
Object &raw_back() {
// Return the element at the end of the list *without* using the iterator classes
// (You may assume the list is not empty)
// Place your code here.
// (Yes, this is bad code. I just needed something that will allow the stub to compile.)
return tail;
}
const Object &back() const { return *--end(); }
void push_front(const Object &x) { insert(begin(), x); }
void push_back(const Object &x) { insert(end(), x); }
void raw_push_front(const Object &x) {
// insert x at the head of the list *without* using the iterator classes
// Place your code here.
Node *p = new Node(x, nullptr, head);
if(tail == nullptr)
tail = p;
head = p;
++theSize;
}
void raw_push_back(const Object &x) {
// insert x at the tail of the list *without* using the iterator classes
// Place your code here.
Node *p = new Node(x, tail, nullptr);
if(head == nullptr)
head = p;
tail = p;
++theSize;
}
void raw_insert_in_order(const Object &x) {
// insert x into the sorted list *without* using the iterator classes.
// You may assume the list is either empty or correctly sorted.
// Place your code here.
}
void push_front(Object &&x) { insert(begin(), std::move(x)); }
void push_back(Object &&x) { insert(end(), std::move(x)); }
void pop_front() { erase(begin()); }
void pop_back() { erase(--end()); }
// Insert x before itr.
iterator insert(iterator itr, const Object &x) {
Node *p = itr.current;
++theSize;
return iterator(p->prev = p->prev->next = new Node{x, p->prev, p});
}
// Insert x before itr.
iterator insert(iterator itr, Object &&x) {
Node *p = itr.current;
++theSize;
return iterator(p->prev = p->prev->next = new Node{std::move(x), p->prev, p});
}
// Erase item at itr.
iterator erase(iterator itr) {
Node *p = itr.current;
iterator retVal(p->next);
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
--theSize;
return retVal;
}
iterator erase(iterator from, iterator to) {
for (iterator itr = from; itr != to;)
itr = erase(itr);
return to;
}
void splice(iterator position, List<Object> &lst ) {
// Removes all the items from lst, add them prior to position in *this.
// You may assume lst and *this are different lists.
// **Your routine must run in constant time.**
Node *p = position.current;
theSize += lst.size();
p->prev->next = lst.head->next;
lst.head->next->prev = p->prev;
lst.tail->prev->next = p;
p->prev = lst.tail->prev;
lst.init();
}
private:
int theSize;
Node *head;
Node *tail;
void init() {
theSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
};
#endif
\ifndef列表
#定义列表
#包括
使用名称空间std;
模板
班级名单{
私人:
//基本的双链接列表节点。
//嵌套在列表中,可以是公共的
//因为节点本身是私有的
结构节点{
对象数据;
节点*prev;
节点*下一步;
节点(const Object&d=Object{},Node*p=nullptr,Node*n=nullptr)
:数据{d},上一个{p},下一个{n}{
节点(对象&d,节点*p=nullptr,节点*n=nullptr)
:data{std::move(d)},prev{p},next{n}
};
公众:
类常量迭代器{
公众:
//常量迭代器的公共构造函数。
常量迭代器():当前{nullptr}{
//返回存储在当前位置的对象。
//对于常量迭代器,这是一个具有
//常量引用返回类型。
常量对象和运算符*()常量{return retrieve();}
常量迭代器和运算符++(){
当前=当前->下一步;
归还*这个;
}
常量迭代器运算符++(int){
常量迭代器old=*this;
++(*本条);
返老还童;
}
常量迭代器和运算符--(){
当前=当前->上一个;
归还*这个;
}
常量迭代器运算符--(int){
常量迭代器old=*this;
--(*本条);
返老还童;
}
bool运算符==(const const_iterator&rhs)const{return current==rhs.current;}
布尔运算符!=(const const_iterator&rhs)const{return!(*this==rhs);}
受保护的:
节点*电流;
//返回对象的常量迭代器中受保护的帮助器
//存储在当前位置。可由所有用户调用
//运算符*的三个版本,没有任何类型转换。
Object&retrieve()常量{返回当前->数据;}
//常量迭代器的受保护构造函数。
//需要一个表示当前位置的指针。
常量迭代器(Node*p):当前{p}{
好友类列表;
};
类迭代器:公共常量迭代器{
公众:
//迭代器的公共构造函数。
//调用基类构造函数。
//必须提供,因为私有构造函数
//写入;否则为零参数构造函数
//将被禁用。
迭代器(){}
对象和运算符*(){return const_iterator::retrieve();}
//返回存储在当前位置的对象。
//对于迭代器,有一个带有
//常量引用返回类型和带有
//引用返回类型。首先显示访问器。
常量对象和运算符*()常量{返回常量迭代器::运算符*()}
迭代器和运算符++(){
本->当前=本->当前->下一步;
归还*这个;
}
迭代器运算符++(int){
迭代器old=*this;
++(*本条);
返老还童;
}
迭代器和运算符--(){
本->当前=本->当前->上一;
归还*这个;
}
迭代器运算符--(int){
迭代器old=*this;
--(*本条);
返老还童;
}
受保护的:
//迭代器的受保护构造函数。
//期望当前位置。
迭代器(Node*p):常量迭代器{p}{
好友类列表;
};
公众:
列表(){init();}
~List(){
//把你的代码放在这里。
清除();
删除标题;
删除尾部;
}
列表(施工列表和rhs){
init();
用于(自动和x:rhs)
推回(x);
}
列表和运算符=(常量列表和rhs){
列表副本=rhs;
std::swap(*本,副本);
归还*这个;
}
List(List&&rhs):大小{rhs.theSize},头{rhs.head},尾{rhs.tail}{
rhs.theSize=0;
rhs.head=空PTR;
rhs.tail=nullptr;
}
列表和运算符=(列表和rhs){
标准::交换(大小,右侧大小);
标准:交换(首部,右侧首部);
标准:交换(尾部,右侧尾部);
归还*这个;
}
//返回表示列表开头的迭代器。
//首先是Mutator版本,然后是accessor版本。
迭代器begin(){返回迭代器(head->next);}
常量迭代器begin()常量{返回常量迭代器(head->next);}
//返回表示列表结束标记的迭代器。
//首先是Mutator版本,然后是accessor版本。
迭代器end(){return iterator(tail);}
const_iterator end()const{return const_iterator(tail);}
//返回列表中当前元素的数目。
int size()常量{返回大小;}
//如果列表为空,则返回true,否则返回false。
bool empty()常量{return size()==0;}
无效清除(){
而(!empty())
pop_front();
}
//前、后、前推、后推、前弹出、后弹出
//是基本的双端队列操作。
Object&front(){return*begin();}
对象&raw_front(){
//返回列表*前面的元素,不使用迭代器类返回*
//(您可以假定列表不是空的)
//(是的,这是错误的代码。我只需要一些允许存根编译的东西。)
回流头;
}
常量对象&front()常量{return*begin();}
Object&back(){return*--end();}
对象&raw_back(){
//使用迭代器类返回列表*末尾的元素,不带*
//(您可以假定列表不是空的)
//把你的代码放在这里。
//(是的,这是错误的代码。我只需要一些允许存根编译的东西。)
返回尾;
}
常量对象&back()常量{return*--end();}
void push_front(const Object&x){insert(begin(),x);}
void push_back(const Object&x){insert(end(),x);}
无效原始推前(常量对象