经典数据结构与算法之循环单链表

18 篇文章 0 订阅
4 篇文章 0 订阅

循环链表是链表的经典变种,它可以解决很多问题。比如有个考察大数据的问题,假如有10亿个数据,如何选出其中最大的十个数。显然,我们可以构造一个大小为10的循环链表,然后依次插入这10亿个数,与之前最大的数进行比较,如果大则插入,否则跳过。思路很简单,循环链表唯一的不同之处是,尾节点的next指针指向头结点。采用带有头结点的链表是比较简单的做法。

具体地说代码如下:

#ifndef CIRCULARLINK_HHH
#define CIRCULARLINK_HHH

template<typename T>
class CCircularLink;

template<typename T>
struct SNode
{
friend CCircularLink<T>;
private:
	T m_nData;
	SNode<T>* m_pNext;
public:
	SNode();
	SNode(T data);
	~SNode();
}; // SNode;

// CCircularLink with a head;
template<typename T>
class CCircularLink{
private:
	// data fields;
	SNode<T>* m_pHead;
public:
	// constructors;
    CCircularLink();
	~CCircularLink();

	// methods;
	void mInsert(const T& data);
    bool mFind(const T& data) const;
	int mDelete();
};  // CCircularLink;

// SNode;
template<typename T>
SNode<T>::SNode():
	m_pNext(NULL){}


template<typename T>
SNode<T>::SNode(T data):
	m_nData(data),m_pNext(NULL){}

template<typename T>
SNode<T>::~SNode() {}


// CCircularLink;
template<typename T>
CCircularLink<T>::CCircularLink(){
	m_pHead = new SNode<T>;
	m_pHead -> m_pNext = m_pHead;
}

template<typename T>
CCircularLink<T>::~CCircularLink(){
	if(m_pHead != NULL){
        SNode<T>* pTmp = m_pHead -> m_pNext;
		while(pTmp != m_pHead){
			SNode<T>* p;
			p = pTmp -> m_pNext;
            delete pTmp;
			pTmp = p;
		}
	    delete m_pHead;
    }
}
// method;
// Insert;
template<typename T>
void CCircularLink<T>::mInsert(const T& data){
	if(NULL != m_pHead){
        SNode<T>* pTmp = m_pHead -> m_pNext;
		SNode<T>* pInsert = new SNode<T>(data);
		pInsert -> m_pNext = pTmp;
		m_pHead -> m_pNext = pInsert;
	}
}
// method;
// Delete;
template<typename T>
int CCircularLink<T>::mDelete(){
	if(NULL != m_pHead){
        SNode<T>* pTmp = m_pHead -> m_pNext;
		if(m_pHead != pTmp){
            m_pHead -> m_pNext = pTmp -> m_pNext;
			delete pTmp;
			return 1;
	    }
    }
	return -1;
}

// method;
// find;
template<typename T>
bool CCircularLink<T>::mFind(const T& data) const{
	if(NULL != m_pHead){ 
	    SNode<T>* pTmp = m_pHead -> m_pNext;
        while(m_pHead != pTmp){
             if(pTmp -> m_nData == data)
		         return true;
			 pTmp = pTmp -> m_pNext;
        }
    }
	return false;
}
#endif


测试代码如下:

#include <iostream>
#include <stdlib.h>
#include "CircularLink.h"
using namespace std;

int main(){
    CCircularLink<int> link;
	link.mInsert(1);
	cout << link.mFind(1) << endl;
	link.mInsert(2);
	link.mInsert(3);
	cout << link.mFind(2) << endl;
	cout << link.mFind(3) << endl;
	cout << link.mFind(4) << endl;
	link.mDelete();
	link.mDelete();
	link.mDelete();

	system("pause");
	return 0;
}

输出如下:

1
1
1
0
请按任意键继续. . .
它与单链表有个一样的缺点,那就是回头太难。所以诞生了双向链表,牺牲了存储的代价。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值