数据结构(五)单向/双向链表交换元素、反向迭代器批量增加/受限删除

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;

}


运行:

猜你喜欢

转载自blog.csdn.net/RayMa0305/article/details/81427657