C ++ implementation of two-way circular list

The blog is a basic operation of the two-way circular list as well as two-way circular linked list on the use of C ++ templates to achieve, before Bowen implement C ++ language doubly linked list , it has been for everyone to analyze the structure of the two-way circular linked list, and is illustrated way to explain the basic operation of the two-way circular linked list. This article use C ++ to achieve the basic operation of the two-way circular list, including:

Two-way circular list Realization of functions
Header insertion node list established Tail insertion node list established
Achieve the specified position of the insertion node Finding the existence of a given value
Node delete the specified location Junction modifying the specified position
Length two-way linked list Print doubly linked list

Doubly linked list of nodes defined

Bidirectional circular linked list node consists of three parts, for pointing direct predecessor of the current node of the pointer field , for storing data elements of the data field , and a direct successor of the current node to point to the target domain .

When before the C ++ language doubly linked list has to explain the characteristics of the junction of the package, do not need to do much to change, we need three elements of a package node class that defines the point of taking and using the constructor to achieve initialization, addition, considering the use in the bidirectional circular list to the node class, the class is defined as the doubly linked list node friend class.

template<class T> 
class doubleCircularLinkedList;//声明一下双向循环链表,以免定义友元时报错
template <class T>
class doubleCircularLinkedListNode
{
	private:
		doubleCircularLinkedListNode<T> *prior;//双向结点前驱指针指向该结点的前驱结点
		T data;//储存结点数据
		doubleCircularLinkedListNode<T> *next;//双向结点的后驱指针指向该结点的后继结点
		//将双向循环链表类定义为结点的友元类
		friend  class doubleCircularLinkedList<T>;
	public:
		//结点的无参构造函数,将结点指针域初始化为NULL
		doubleCircularLinkedListNode()
		{
			prior = NULL;
			next = NULL;
		}
		//结点的有参构造函数,初始化指针域和数据域
		doubleCircularLinkedListNode(T _data,doubleCircularLinkedListNode<T> *_prior = NULL,doubleCircularLinkedListNode<T> *_next = NULL)
		{
			prior = _prior;//初始化前驱指针
			data = _data;//初始化数据域
			next = _next;//初始化后继指针
		}
		~doubleCircularLinkedListNode()
		{
			prior = NULL;
			next = NULL;
		}
};

The basic operation of a doubly linked list

Operation with operating a doubly linked list to achieve essentially the same, to achieve a two-way circular linked list node insertion head, the tail insertion node, specify the location of the insertion node to establish the list and look to the designated location of a given value, delete the specified location of this implementation node, node modify the specified position, the length of the two-way circular linked list, printing two-way circular linked list, one by one to the next explain implemented:

Header insertion node list established

Head insertion bidirectional circular list node, the previous since the doubly linked list head and tail pointers are pointing to NULL , it is necessary to process the sub-case, however, two way circular linked list pointer is not pointing element itself, and therefore does not need to deal with the case of division, four pointers need to be modified.
Thus, the head insertion node implemented as follows:

template<class T>
bool doubleCircularLinkedList<T>::insertNodeByhead(T item)
{
	//创建一个新的结点
	doubleCircularLinkedListNode<T>* newNode = new doubleCircularLinkedListNode<T>(item);
	if (newNode == NULL){
		cout << "内存分配失败,新结点无法创建" << endl;
		return false;
	}
	else{
		newNode->prior = headNode;
		newNode->next = headNode->next;
		headNode->next->prior=newNode;
		headNode->next = newNode;
		return true;
	}
}

Tail insertion node list established

The insertion node at the end, of course, a first step is to find the last node, and then thereafter inserted, adjusted to four pointers.

template<class T>
bool doubleCircularLinkedList<T>::insertNodeBytail(T item)
{
	//创建一个新的结点
	doubleCircularLinkedListNode<T>* newNode = new doubleCircularLinkedListNode<T>(item);
	if (newNode == NULL){
		cout << "内存分配失败,新结点无法创建" << endl;
		return false;
	}
	//首先找到最后一个结点
	doubleCircularLinkedListNode<T>* lastNode = headNode;
	while(lastNode->next != headNode)
	{
		lastNode = lastNode->next;//没找到就一直循环
	}
	//找到之后调整四个指针
	headNode->prior = newNode;
	newNode->next = headNode;
	lastNode->next = newNode;
	newNode->prior = lastNode;
	return true;
}

Achieve the specified position of the insertion node

Only need to insert a two-step at the specified location, the first and find the specified location, then adjust the pointer is to insert a new node, intervening is the most complex, all four need to adjust the pointer, and let the new node and the predecessor node to establish relations and realize the insertion of new nodes.

template<class T>
bool doubleCircularLinkedList<T>::insertNode(T item,int n)
{
	if(n<1){
		cout<<"输入的非有效位置!"<<endl;
		return false;
	}
	doubleCircularLinkedListNode<T>* pMove = headNode;//创建一个新的指针,设置为游标指针
	//首先找到插入位置
	for(int i=1;i<n;i++)
	{
		pMove = pMove->next;
		if(pMove == NULL&& i<=n)
		{
			cout<<"插入位置无效!"<<endl;
			return false;
		}
	}
	//创建一个新的结点
	doubleCircularLinkedListNode<T>* newNode = new doubleCircularLinkedListNode<T>(item);
	if (newNode == NULL){
		cout << "内存分配失败,新结点无法创建" << endl;
		return false;
	}
	//插入新的结点
	newNode->next = pMove->next;   
	if (pMove->next != headNode)
	{
		pMove->next->prior = newNode;
	}
	newNode->prior = pMove;
	pMove->next = newNode;
	return true;
}

Finding the existence of a given value

Find a given element, which is a two-way circular linked list traversal process from scratch the next node node traversing, after all, the first head node is not stored data items.

template<class T>
bool doubleCircularLinkedList<T>::findData(T item)
{
	doubleCircularLinkedListNode<T> *pMove = headNode->next; //设置游标指针
	doubleCircularLinkedListNode<T> *pMoveprior = headNode;//指定结点前一个结点的指针
	//找到指定位置
	while(pMove->data != item)
	{
		pMoveprior = pMove;
		pMove = pMoveprior->next;
		//如果没有找到特殊处理
		if(pMove == headNode)
		{
			return false;
		}
	}
	return true;
}

Node delete the specified location

Delete the specified node, the first step to find the node to delete, delete the need to define a temporary pointer pointing to the node to be deleted, do not forget to delete pointer processing after the last release of the node space.

template<class T>
bool doubleCircularLinkedList<T>::deleteData(int n)
{
	if (n<1||n>getLength())
	{
		cout << "输入非有效位置" << endl;
		return false;
	}
	doubleCircularLinkedListNode<T> * pMove = headNode;//设置游标指针
	doubleCircularLinkedListNode<T> * pDelete;             
	//查找删除结点的位置
	for (int i = 1; i <= n; i++)
	{
		pMove = pMove->next;                                         //游标指针后移
	}
	//删除结点
	pDelete = pMove;      
	pMove->prior->next = pDelete->next;
	pMove->next->prior = pDelete->prior;
	delete pDelete;//释放空间
	return true;
}

Junction modifying the specified position

Modify node data specified position, of course, still have to find the specified location, and then modify it, after modifying the original data returned in the form by reference.

template<class T>
bool doubleCircularLinkedList<T>::changeListElements(int n,T item,T &x)
{
	if (n<1||n>getLength())
	{
		cout << "输入非有效位置" << endl;
		return false;
	}
	doubleCircularLinkedListNode<T> *pMove = headNode->next;  //设置游标指针
	for(int i=1;i<n;i++)//找到指定位置1
	{
		pMove = pMove->next;
	}
	x = pMove->data;
	pMove->data = item;
	return true;
}

Length two-way linked list

Calculating a function of the length of the doubly linked list, a doubly linked list in a package private members of a variable length , in order to record the length of the doubly linked list, a doubly linked list traversal, the number of nodes is calculated one by one length of a doubly linked list.

template<class T>
int doubleCircularLinkedList<T>::getLength()
{
	doubleCircularLinkedListNode<T> *pMove = headNode->next;  //设置游标指针
	int length=0;
	//遍历链表,计算结点数
	while(pMove != headNode)
	{
		pMove = pMove->next;  //游标指针后移
		length++;       //计算length
	}
	return length;
}

Print doubly linked list

template<class T>
void doubleCircularLinkedList<T>::printLinkedlist()
{
	//从第二个结点开始打印,表头不含数据
	doubleCircularLinkedListNode<T>* pMove = headNode->next;
	while(pMove !=headNode)//如果pMove->next != headNode这样写,最后一个结点是不会打印的
	{
		cout<<pMove->data<<" ";
		pMove = pMove->next;//移动指针
	}
	cout<<endl;
}

That is all I briefly to share C ++ implementation of two-way circular linked list, because the realization of a doubly linked list, so basically the realization of ideas about the same, the only difference is in circulation different word, precursors pointer and the tail of this difference is that the first node after flooding pointer points to a different node, and if still not clear thing I read blog can go and see. The complete code have all been uploaded to GitHub! (C ++ two-way circular linked list) , I want to know you can go to the other data structure implemented blog , we discuss ah, progress together!

Published 19 original articles · won praise 8 · views 592

Guess you like

Origin blog.csdn.net/qq_43336390/article/details/104215071