单链表的一个C++实现
来源:互联网 发布:如何发起淘宝众筹项目 编辑:程序博客网 时间:2024/05/19 10:53
下面是单链表的一个C++实现,参考了《数据结构与算法分析C语言版》及不少牛人的分析总结,在此一并感谢了。在VC2005上经反复验证试验,结果非常不错。但可能还有不少bug,如果发现bug, 请告诉我一下。
注意:单链表及双向及循环链表均不适用表头(即哑节点,dummy node), 即m_pNodeHead指针指向链表的第一个真正节点。
/*slist.h*/#include <assert.h>#include <crtdbg.h>template<typename T>//class T must have default constructorclass Node{public:T data;Node<T> *next;Node() : data(T()), next(NULL) {}Node(const T &initdata) : data(initdata), next(NULL) {}Node(const T &initdata, Node<T> *p) : data(initdata), next(p) {}};template<typename T>class SList{public:SList();SList(const T &initdata);SList(const SList<T>& other);SList<T>& operator=(const SList<T>& other);~SList();public:void Invert();int IsEmpty() const;int GetCount() const;int InsertBefore(const int pos, const T data);int InsertAfter(const int pos, const T data);int AddHead(const T data);int AddTail(const T data);void RemoveAt(const int pos);void RemoveHead();void RemoveTail();void RemoveAll();T& GetTail();T GetTail() const;T& GetHead();T GetHead() const;T& GetAt(const int pos);T GetAt(const int pos) const;void SetAt(const int pos, T data);int Find(const T data) const; int FindCircle() const;int FindCross(SList& testlist);protected:int m_nCount;Node<T> *m_pNodeHead;};template<typename T>inline SList<T>::SList() : m_nCount(0), m_pNodeHead(NULL){}template<typename T>inline SList<T>::SList(const T &initdata) : m_nCount(0), m_pNodeHead(NULL){AddHead(initdata);}template<typename T>inline SList<T>::SList(const SList<T>& other) : m_nCount(0), m_pNodeHead(NULL){if(other.m_nCount>0){for(int i=1;i<=other.m_nCount;i++){AddTail(other.GetAt(i));}}}template<typename T>inline SList<T>& SList<T>::operator=(const SList<T>& other){if(this==&other){return *this;}if(m_nCount>0){RemoveAll();}if(other.m_nCount>0){for(int i=1;i<=other.m_nCount;i++){AddTail(other.GetAt(i));}}return *this;}template<typename T>inline SList<T>::~SList(){RemoveAll();}//reverse the listtemplate<typename T>inline void SList<T>::Invert(){if(m_nCount<=1) return;Node<T> *curNod,*preNod,*nextNod;curNod=m_pNodeHead;preNod=NULL;for(int i=1;i<=m_nCount;i++){nextNod=curNod->next;curNod->next=preNod;preNod=curNod;curNod=nextNod;} m_pNodeHead=preNod; return;}template<typename T>inline int SList<T>::IsEmpty() const{return 0 == m_nCount;}template<typename T>inline int SList<T>::AddHead(const T data){/*Node<T> *pNewNode;try{pNewNode = new Node<T>;}catch (std::bad_alloc&) {return 0;}pNewNode->data = data;pNewNode->next = m_pNodeHead;m_pNodeHead = pNewNode;++m_nCount;return 1;*/return InsertBefore(1,data);}template<typename T>inline int SList<T>::AddTail(const T data){return InsertAfter(GetCount(), data);}// if success, return the position of the new node.// if fail, return 0.template<typename T>inline int SList<T>::InsertBefore(const int pos, const T data){int i;int nRetPos;Node<T> *pTmpNode1;Node<T> *pTmpNode2;Node<T> *pNewNode;try{pNewNode = new Node<T>;}catch (std::bad_alloc&) {nRetPos = 0;return nRetPos;}pNewNode->data = data;// if the list is empty, replace the head node with the new node.if (NULL == m_pNodeHead){pNewNode->next = NULL;m_pNodeHead = pNewNode;nRetPos = 1;++m_nCount;return nRetPos;}// is pos range valid?ASSERT(1 <= pos && pos <= m_nCount);// insert before head node?if (1 == pos){pNewNode->next = m_pNodeHead;m_pNodeHead = pNewNode;nRetPos = 1;++m_nCount;return nRetPos;}// if the list is not empty and is not inserted before head node,// seek to the pos of the list and insert the new node before it.pTmpNode1 = m_pNodeHead;for (i = 1; i < pos; ++i){pTmpNode2 = pTmpNode1;pTmpNode1 = pTmpNode1->next;}pNewNode->next = pTmpNode1;pTmpNode2->next = pNewNode;nRetPos = pos;++m_nCount;return nRetPos;}// if success, return the position of the new node.// if fail, return 0.template<typename T>inline int SList<T>::InsertAfter(const int pos, const T data){int i;int nRetPos;Node<T> *pTmpNode;Node<T> *pNewNode;try{pNewNode = new Node<T>;}catch (std::bad_alloc&) {nRetPos = 0;return nRetPos;}pNewNode->data = data;// if the list is empty, replace the head node with the new node.if (NULL == m_pNodeHead){pNewNode->next = NULL;m_pNodeHead = pNewNode;nRetPos = 1;++m_nCount;return nRetPos;}// is pos range valid?ASSERT(1 <= pos && pos <= m_nCount);// if the list is not empty,// seek to the pos of the list and insert the new node after it.pTmpNode = m_pNodeHead;for (i = 1; i < pos; ++i){pTmpNode = pTmpNode->next;}pNewNode->next = pTmpNode->next;pTmpNode->next = pNewNode;nRetPos = pos + 1;++m_nCount;return nRetPos;}template<typename T>inline int SList<T>::GetCount() const{return m_nCount;}template<typename T>inline void SList<T>::RemoveAt(const int pos){ASSERT(1 <= pos && pos <= m_nCount);int i;Node<T> *pTmpNode1;Node<T> *pTmpNode2;pTmpNode1 = m_pNodeHead;// head node?if (1 == pos){m_pNodeHead = m_pNodeHead->next;delete pTmpNode1;--m_nCount;return;}for (i = 1; i < pos; ++i){// we will get the previous node of the target node after// the for loop finished, and it would be stored into pTmpNode2pTmpNode2 = pTmpNode1;pTmpNode1 = pTmpNode1->next;}pTmpNode2->next = pTmpNode1->next;delete pTmpNode1;--m_nCount;}template<typename T>inline void SList<T>::RemoveHead(){ASSERT(0 != m_nCount);RemoveAt(1);}template<typename T>inline void SList<T>::RemoveTail(){ASSERT(0 != m_nCount);RemoveAt(m_nCount);}template<typename T>inline void SList<T>::RemoveAll(){int i;int nCount;Node<T> *pTmpNode;nCount = m_nCount;if(nCount==0){return;}for (i = 0; i < nCount; ++i){pTmpNode = m_pNodeHead->next;delete m_pNodeHead;m_pNodeHead = pTmpNode;}m_pNodeHead=NULL;m_nCount = 0;}template<typename T>inline T& SList<T>::GetTail(){ASSERT(0 != m_nCount);int i;int nCount;Node<T> *pTmpNode = m_pNodeHead;nCount = m_nCount;for (i = 1; i < nCount; ++i){pTmpNode = pTmpNode->next;}return pTmpNode->data;}template<typename T>inline T SList<T>::GetTail() const{ASSERT(0 != m_nCount);int i;int nCount;Node<T> *pTmpNode = m_pNodeHead;nCount = m_nCount;for (i = 1; i < nCount; ++i){pTmpNode = pTmpNode->next;}return pTmpNode->data;}template<typename T>inline T& SList<T>::GetHead(){ASSERT(0 != m_nCount);return m_pNodeHead->data;}template<typename T>inline T SList<T>::GetHead() const{ASSERT(0 != m_nCount);return m_pNodeHead->data;}template<typename T>inline T& SList<T>::GetAt(const int pos){ASSERT(1 <= pos && pos <= m_nCount);int i;Node<T> *pTmpNode = m_pNodeHead;for (i = 1; i < pos; ++i){pTmpNode = pTmpNode->next;}return pTmpNode->data;}template<typename T>inline T SList<T>::GetAt(const int pos) const{ASSERT(1 <= pos && pos <= m_nCount);int i;Node<T> *pTmpNode = m_pNodeHead;for (i = 1; i < pos; ++i){pTmpNode = pTmpNode->next;}return pTmpNode->data;}template<typename T>inline void SList<T>::SetAt(const int pos, T data){ASSERT(1 <= pos && pos <= m_nCount);int i;Node<T> *pTmpNode = m_pNodeHead;for (i = 1; i < pos; ++i){pTmpNode = pTmpNode->next;}pTmpNode->data = data;}template<typename T>inline int SList<T>::Find(const T data) const{int i;int nCount;Node<T> *pTmpNode = m_pNodeHead;nCount = m_nCount;for (i = 0; i < nCount; ++i){if (data == pTmpNode->data)return i + 1;pTmpNode = pTmpNode->next;}return 0;}/*判断链表是否有环,如果有环则返回环的首结点位置,否则返回0*/ template<typename T>inline int SList<T>::FindCircle() const{if(0==m_nCount){return 0;} Node<T>* p1=m_pNodeHead;Node<T>* p2=m_pNodeHead;/*判断链表是否有环,当p1=p2时说明链表有环,程序跳出循环。如果p2一直走到链表尽头则说明没有环。*/ do{ if(p1!=NULL&&p2!=NULL&&p2->next!=NULL) { p1=p1->next; p2=p2->next->next; } else return 0; } while(p1!=p2); /*求出环的起点节点,并将其返回*/ p2=m_pNodeHead; while(p1!=p2) { p1=p1->next; p2=p2->next; } int i;p2=m_pNodeHead; for(i=1;i<=m_nCount;i++){if(p1==p2) break;p2=p2->next;}return i;}/*判断两个链表是否交叉,如果交叉返回首个交叉节点位置(在本链表中的位置,而不是testlist中的位置),否则返回0。假定:这两个链表本身均无环*/ template<typename T>inline int SList<T>::FindCross(SList& testlist){if(0==m_nCount||0==testlist.m_nCount){return 0;} if(FindCircle()||testlist.FindCircle()){return 0;}/*将第二个链表接在第一个链表后面*/ Node<T>* pTail=m_pNodeHead;for(int i=1;i<m_nCount;i++){pTail=pTail->next;}pTail=testlist.m_pNodeHead;m_nCount+=testlist.m_nCount;int i=FindCircle();pTail=NULL;m_nCount-=testlist.m_nCount;return i;}#endif
- C语言一个单链表的实现
- C语言一个单链表的实现
- 一个算法的C实现
- 红黑树的一个C实现
- 一个双链表的C实现
- 一个双链表的C实现
- C-一个栈的实现
- red_black_tree的一个实现(c/c++)
- C语言实现一个单链表
- 一个简单的C单链表实现和错误总结
- 一个简单的http_server的c实现
- c实现的一个经典链表
- 用C实现的一个cstring
- 一个简单的HashMap C语言实现
- [C#]StringWriter实现的一个功能
- 一个urlencode/urldecode的C实现
- C语言一个库函数的实现
- 一个简单的HashMap C语言实现
- 【翻译WINDOWS NT FILE SYSTEM INTERNAL】NT缓存管理器一(3)
- 《Android开发从零开始》——36.TabWidget控件学习
- ps cs4安装时发生错误——下载所选选件的大小超过安装位置的可用磁盘空间
- 再谈 PyChecker 在游戏引擎环境下的使用
- URL重写
- 单链表的一个C++实现
- 数据类型/Date
- android中用SurfaceHolder处理SurfaceView的画图
- spi
- windows 7旗舰版64位 安装 Oracle 10g
- 【翻译WINDOWS NT FILE SYSTEM INTERNAL】NT缓存管理器一(4)
- u-boot 的NAND启动方式
- 仅应用于内部互连的PCIe
- opengl绘制固定宽度多边形圆角边框算法(历时周半,撰博文以志纪念)II