1、单向链表交换相邻元素
代码:
//请在DEV中运行,先勾选“Tools" -勾选”Compailer Options"-再勾选"Add~~~“-框框中输入"-std=c++11”
#include<iostream>
#include <algorithm>
using namespace std;
template<typename Object>
//定义变量和指针变量
struct Node{
Object num;
Node *next;
};
typedef Node<int>PNODE;//实例化int对象PNODE
//创建链表,n为链表中int对象的个数
PNODE* Create(int n)
{
PNODE *phead = new PNODE;
phead->next = nullptr;
PNODE *PTlie = phead;
for(int i = 0; i < n; i++)
{
PNODE *pnew =new PNODE;
pnew->num = i;//顺向建立链表
pnew->next =nullptr;
PTlie->next = pnew;
PTlie = pnew;
}
return phead;
}
//交换
void Swap(PNODE *p,int n)//交换是当前位置和后面一个位置交换
{
int i = 0;
while(i != n - 1 && p->next != nullptr)//记录要交换结点的前一个结点
{
p = p->next;
i++;
}
if(p->next == nullptr)
{
printf("无法交换");
return ;
}
PNODE *p1,*p2;//定义p1,p2分别记录要交换两个结点
p1 = p->next;
p2 = p1->next;
p1->next = p2->next;
p->next = p2;
p2->next = p1;
}
//输出链表
void print(PNODE *p)
{
p = p->next;
for(int i = 0;p != nullptr; i++)
{
printf("%d ",p->num);
p = p->next;
}
printf("\n\n");
}
int main(void)
{
PNODE *p = Create(20);//创建一个含20位int的链表
int n;
cout<<"输出原链表:"<<endl;
print(p);
printf("输入要交换的位置:");
cin>>n;//交换是当前位置和后面一个位置交换
cout<<endl;
Swap(p,n);
cout<<"输出交换后的链表:"<<endl;
print(p);
return 0;
}
运行:
2、双向链表交换元素
代码:
//请在DEV中运行,先勾选“Tools" -勾选”Compailer Options"-再勾选"Add~~~“-框框中输入"-std=c++11”
#include<iostream>
#include <algorithm>
using namespace std;
template<typename Object>
struct Node{
Object num;
struct Node * next;
struct Node * last;
};
typedef Node<int> PNODE;
int length;//不设置初始化数值,自定义链表
//创建一个双向循环链表
PNODE* Create()
{
PNODE *phead = new PNODE;
phead->next = phead;
phead->last = phead;
PNODE *PTlie = phead;
cin>>length;
for(int i = 0; i < length; i++)
{
PNODE *pnew = new PNODE;
pnew->num = i;
pnew->next = phead;
pnew->last = PTlie;
PTlie->next = pnew;
PTlie = pnew;
}
return phead;
}
//交换是当前位置和后面一个位置交换
void swap(PNODE *p,int n)
{
int i = 0;
while(i != n - 1 && p->next != NULL)//记录要交换结点的前一个结点
{
p = p->next;
i++;
}
PNODE *p1,*p2;//定义p1,p2分别记录要交换两个结点
p1 = p->next;
p2 = p1->next;
p1->next = p2->next;
p2->next->last = p1;//这里注意,如果是双向不循环链表的话,最后两个数交换,会导致程序错误。因为p2->next为空
p->next = p2;
p2->last = p;
p2->next = p1;
p1->last = p2;
}
//输出链表
void print(PNODE *p,int length)
{
p = p->next;
for(int i = 0; i < length; i++)
{
cout<<p->num<<" ";
p = p->next;
}
cout<<endl;
}
int main()
{ cout<<"输入length:";
PNODE *p = Create();//创建链表
print(p,length);
int n;
cout<<"输入要交换的位置:";
cin>>n;
swap(p,n);
cout<<"输出交换后的链表";
print(p,length);
return 0;
}
运行:
3、反向迭代器
代码:
//请在DEV中运行,先勾选“Tools" -勾选”Compailer Options"-再勾选"Add~~~“-框框中输入"-std=c++11”
#ifndef LIST_H
#define LIST_H
#include<iostream>
#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>;
};
/////////////////////////////////////////////////////////////
//反向迭代器iterator
class const_reverse_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.
const_reverse_iterator() : current{ nullptr }
{ }
// 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 retrieve();
}
const_reverse_iterator & operator++ ()
{
this->current = this->current->prev;
return *this;
}
const_reverse_iterator operator++ (int)
{
const_reverse_iterator old = *this;
--(*this);
return old;
}
const_reverse_iterator & operator-- ()
{
current = current->next;
return *this;
}
const_reverse_iterator operator-- (int)
{
const_reverse_iterator old = *this;
++(*this);
return old;
}
bool operator== (const const_reverse_iterator & rhs) const
{
return current == rhs.current;
}
bool operator!= (const const_reverse_iterator & rhs) const
{
return !(*this == rhs);
}
protected:
Node *current;
Object & retrieve() const
{
return current->data;
}
// Protected constructor for iterator.
// Expects the current position.
const_reverse_iterator(Node *p) : current{ p }
{ }
friend class List<Object>;
};
///////////////////////////////////////////////////////////
class reverse_iterator : public const_reverse_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.
reverse_iterator()
{ }
Object & operator* ()
{
return const_reverse_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_reverse_iterator::operator*();
}
reverse_iterator & operator++ ()
{
reverse_iterator old = *this;
--(*this);
return old;
}
reverse_iterator operator++ (int)
{
this->current = this->current->prev;
return *this;
}
reverse_iterator & operator-- ()
{
reverse_iterator old = *this;
++(*this);
}
reverse_iterator operator-- (int)
{
this->current =this-> current->next;
return *this;
}
protected:
// Protected constructor for iterator.
// Expects the current position.
reverse_iterator(Node *p) : const_reverse_iterator{ p }
{ }
friend class List<Object>;
};
public:
List()
{
init();
}
~List()
{
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);
}
reverse_iterator rbegin()
{
return reverse_iterator(tail->prev);
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(tail->prev);
}
// Return iterator representing endmarker of list.
// Mutator version is first, then accessor version.
reverse_iterator rend()
{
return reverse_iterator(head);
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(head);
}
// 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();
}
const Object & front() const
{
return *begin();
}
Object & back()
{
return *--end();
}
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 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;
}
private:
int theSize;
Node *head;
Node *tail;
void init()
{
theSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
};
#endif
int main()//测试程序
{
List<int>a1;
a1.push_back(1);
a1.push_back(2);
a1.push_back(3);
a1.push_back(4);
List<int>::iterator it;
for (it = a1.begin(); it != a1.end(); it++) {
cout << *it << "\t";
}
cout << endl;
a1.insert(a1.begin(), 0);
cout << "在a1[0]处插入0:" << endl;
for (it = a1.begin(); it != a1.end(); it++) {
cout << *it << "\t";
}
cout << endl;
a1.erase(a1.begin());
cout << "在a1[0]处删除0:" << endl;
for (it = a1.begin(); it != a1.end(); it++) {
cout << *it << "\t";
}
cout << endl;
cout << "调用反向迭代器输出:" << endl;
List<int>::reverse_iterator itr;
for (itr = a1.rbegin(); itr != a1.rend(); itr++)
{
cout << *itr << "\t";
}
cout << endl;
a1.erase(a1.begin(), a1.end());
cout << "删除全部的元素:" << endl;
for (it = a1.begin(); it != a1.end(); it++) {
cout << *it << "\t";
}
cout << endl;
system("pause");
return 0;
}
运行:
4、批量增加
代码:
//请在DEV中运行,先勾选“Tools" -勾选”Compailer Options"-再勾选"Add~~~“-框框中输入"-std=c++11”
#include<iostream>
#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( )
{
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( ); }
const Object & front( ) const
{ return *begin( ); }
Object & back( )
{ return *--end( ); }
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 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( ) ); }
void addAll(iterator position, List<Object> & lst)
{
this->theSize += lst.theSize;
iterator end1{ lst.end() };
iterator begin1{ lst.begin() };
end1--;
lst.init();
iterator tmp;
tmp = position;
tmp--;
position.current->prev = end1.current;
end1.current->next = position.current;
tmp.current->next = begin1.current;
begin1.current->prev = tmp.current;
this->theSize += lst.theSize;
}
// 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;
}
private:
int theSize;
Node *head;
Node *tail;
void init( )
{
theSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
};
int main()
{
List<int> a,b;
a.push_back(1);
a.push_back(2);
a.push_back(3);
b.push_back(2);
cout<<"a的长度:"<<a.size()<<endl;
cout<<"b的长度:"<<b.size()<<endl;
List<int>::iterator it;
cout<<"输出a:"<<endl;
for (it = a.begin(); it != a.end(); it++){
cout << *it << "\t";
}
cout << endl;
cout<<"输出b:"<<endl;
for (it = b.begin(); it != b.end(); it++){
cout << *it << "\t";
}
cout << endl;
cout<<"addAll 操作"<<endl;
a.addAll(a.begin(), b);
cout<<"a的长度:"<<a.size()<<endl;
cout<<"b的长度:"<<b.size()<<endl;
cout<<"输出a:"<<endl;
for (it = a.begin(); it != a.end(); it++){
cout << *it << "\t";
}
cout << endl;
cout<<"输出b:"<<endl;
for (it = b.begin(); it != b.end(); it++){
cout << *it << "\t";
}
cout << endl;
return 0;
}
运行:
5、受限删除
代码:
//请在DEV中运行,先勾选“Tools" -勾选”Compailer Options"-再勾选"Add~~~“-框框中输入"-std=c++11”
#include<iostream>
using namespace std;
template <typename Object>
//定义变量和指针变量
struct Node
{
Object data;
Node *next;
Node(const Object & d = Object{}, Node *n = nullptr) :data(d), next(n)
{}
};
template <typename Object>
void pDelete(Node<Object>* ptrX)//定义一个删除函数
{
Node<Object>*p ;
p = ptrX->next;
ptrX->next = p->next;
ptrX->data = p->data;
delete p;
p = nullptr;
}
int main()
{
typedef Node<int>node;
node *head = new node;
node *p, *q;
int n = 20;
p = head;
for (int i = 0; i < n; i++)
{
q = new node{ i,head };
p->next = q;
q->next = NULL;
p = q;
}
p = head->next;
while (p != nullptr)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
int m;
cout<<"请输出要删除的数据:"<<endl;
cin>>m;
node *s=head->next;
while(s->data!=m)
s=s->next;
pDelete(s);
p = head->next;
while (p != nullptr)
{
cout << p->data << " ";
p = p->next;
}
return 0;
}
运行: