迴圈單向鏈表
1. 迴圈單向鏈表如何?。
迴圈單向鏈表只是在單向鏈表的基礎上使尾結點指向頭結點。因為每次插入結點,新結點都是指向上一個結點當前的下一個結點。因此在單向鏈表的基礎上,我們使頭結點指向自身即可。
因此只需要在以前的博文單鏈表代碼中的建構函式初始化的時候,加上一行代碼,便做到了迴圈:
m_pHeadNode->SetNext(m_pHeadNode); 2. 實現(C++代碼)
//CircularSinglyLink.h#pragma once#include <assert.h>#include <stdio.h>template<typename ElemType>class Node{public: Node(Node<ElemType>* pNext = NULL, ElemType* pData = NULL); ElemType const& GetData() const; void SetData(ElemType val) ; Node<ElemType>* const& GetNext() const; void SetNext(Node<ElemType>* val);private: ElemType* m_pData; Node<ElemType>* m_pNext;};template<typename ElemType>class CircularSinglyLink{public: CircularSinglyLink(); unsigned int const& GetLength() const; bool Insert(ElemType elem, unsigned int pos); bool InsertByPosNode(ElemType elem, Node<ElemType>* posNode, Node<ElemType>** RetInsetNode = NULL); bool Delete(unsigned int pos, ElemType* elem); bool Search(unsigned int pos, ElemType* elem) const; bool Visit(ElemType* elem, const unsigned int& pos) const; bool Empty(); Node<ElemType>* HavaHeadNode();private: Node<ElemType>* m_pHeadNode; unsigned int m_length;};//————————————————————————————————//Node類的實現template<typename ElemType>Node<ElemType>::Node(Node<ElemType>* pNext /*= NULL*/, ElemType* pData /*= NULL*/) :m_pNext(pNext),m_pData(pData){}template<typename ElemType>void Node<ElemType>::SetNext(Node<ElemType>* val){ m_pNext = val;}template<typename ElemType>Node<ElemType>* const& Node<ElemType>::GetNext() const{ return m_pNext;}template<typename ElemType>void Node<ElemType>::SetData(ElemType val){ m_pData = val;}template<typename ElemType>ElemType const& Node<ElemType>::GetData() const{ return *m_pData;}//————————————————————————————————//SinglyLink類實現template<typename ElemType>CircularSinglyLink<ElemType>::CircularSinglyLink() :m_pHeadNode(new Node<ElemType>()),m_length(0){ m_pHeadNode->SetNext(m_pHeadNode);}template<typename ElemType>bool CircularSinglyLink<ElemType>::InsertByPosNode(ElemType elem, Node<ElemType>* posNode, Node<ElemType>** RetInsetNode /*= NULL*/){ Node<ElemType>* insertNode = new Node<ElemType>(posNode->GetNext(),new ElemType(elem)); posNode->SetNext(insertNode); ++m_length; *RetInsetNode = insertNode; return true;}template<typename ElemType>bool CircularSinglyLink<ElemType>::Insert(ElemType elem, unsigned int pos){ if (pos > GetLength() || pos < 0) { assert(false && "Error: SinglyLink's insert pos is out of range!\n"); return false; } for(Node<ElemType>* pCurrentNode = m_pHeadNode; pCurrentNode != NULL; pCurrentNode = pCurrentNode->GetNext()) { if (pos-- == 0) { Node<ElemType>* insertNode = new Node<ElemType>(pCurrentNode->GetNext(),new ElemType(elem)); pCurrentNode->SetNext(insertNode); ++m_length; return true; } } assert(false && "Error: SinglyLink Insert failed for unknow reason!"); return false;}template<typename ElemType>bool CircularSinglyLink<ElemType>::Delete(unsigned int pos, ElemType* elem){ if (pos >= GetLength() || pos < 0) { assert(false && "Error: SinglyLink's delete pos is out of range!\n"); } for(Node<ElemType>* pCurrentNode = m_pHeadNode; pCurrentNode != NULL; pCurrentNode = pCurrentNode->GetNext()) { if (pos-- == 0) { Node<ElemType>* deleteNode = pCurrentNode->GetNext(); pCurrentNode->SetNext(deleteNode->GetNext()); *elem = deleteNode->GetData(); delete deleteNode; --m_length; return true; } } assert(false && "Error: SinglyLink pos delete failed for unknow reason!"); return false;}template<typename ElemType>unsigned int const& CircularSinglyLink<ElemType>::GetLength() const{ return m_length;}template<typename ElemType>bool CircularSinglyLink<ElemType>::Search(unsigned int pos, ElemType* elem) const{ if (pos >= GetLength() || pos < 0) { assert(false && "Error: SinglyLink's search pos is out of range!\n"); } for(Node<ElemType>* pCurrentNode = m_pHeadNode; pCurrentNode != NULL; pCurrentNode = pCurrentNode->GetNext()) { if (pos-- == 0 && (pCurrentNode->GetNext() != NULL) ) { *elem = pCurrentNode->GetNext()->GetData(); return true; } } return false;}template<typename ElemType>bool CircularSinglyLink<ElemType>::Visit(ElemType* elem, const unsigned int& pos) const{ if (pos >= GetLength() || pos < 0) { return false; } return Search(pos,elem);}template<typename ElemType>bool CircularSinglyLink<ElemType>::Empty(){ return !m_length;}template<typename ElemType>Node<ElemType>* CircularSinglyLink<ElemType>::HavaHeadNode(){ return m_pHeadNode;}
//Util.h#pragma oncenamespace Util{ template<typename T> void PrintMemory(const T& dateStruct, unsigned int size) { cout << "PrintMemory: "; for (int i = 0; i != size; i++) { ElemType tempElem; if (!dateStruct.Visit(&tempElem,i)) { printf("\n"); return; } printf("%d ",tempElem); } printf("\n"); }}
//main.cpp#include "Util.h"#include "CircularSinglyLink.h"#include <iostream>using namespace std;typedef int ElemType;int main(){ CircularSinglyLink<int> testCircularSinglyLink; cout << "testCircularSinglyLink is " << (testCircularSinglyLink.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testCircularSinglyLink,testCircularSinglyLink.GetLength()); for (int i = 0; i != 5; i++) { testCircularSinglyLink.Insert(i+1,i); cout << "\nInsert:" << i << endl; cout << "testCircularSinglyLink is " << (testCircularSinglyLink.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testCircularSinglyLink,testCircularSinglyLink.GetLength()); } for (int i = 0; i != 2; i++) { ElemType tempElem; testCircularSinglyLink.Delete(i,&tempElem); cout << "\nDelete:" << tempElem << endl; cout << "testCircularSinglyLink is " << (testCircularSinglyLink.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testCircularSinglyLink,testCircularSinglyLink.GetLength()); } return 0;}
3. 程式運行結果
testCircularSinglyLink is Empty.
PrintMemory:
Insert:0
testCircularSinglyLink is Not Empty.
PrintMemory: 1
Insert:1
testCircularSinglyLink is Not Empty.
PrintMemory: 1 2
Insert:2
testCircularSinglyLink is Not Empty.
PrintMemory: 1 2 3
Insert:3
testCircularSinglyLink is Not Empty.
PrintMemory: 1 2 3 4
Insert:4
testCircularSinglyLink is Not Empty.
PrintMemory: 1 2 3 4 5
Delete:1
testCircularSinglyLink is Not Empty.
PrintMemory: 2 3 4 5
Delete:3
testCircularSinglyLink is Not Empty.
PrintMemory: 2 4 5