循环链表

/*
 * =====================================================================================
 *
 *       Filename:  d_list.h
 *
 *    Description:  看了循环链表,写个代码练习练习 
 *                      循环链表
 *			优点:  删除操作节点或整个链表的操作可以在常数的时间内完成
 *					
 *
 *        Version:  1.0
 *        Created:  08/25/2012 05:55:21 PM
 *       Revision:  none
 *       Compiler:  g++
 *
 *         Author:  lsff (lsff), 
 *   Organization:  
 *
 * =====================================================================================
 */


#ifndef CLIST_H
#define CLIST_H
#include 
using namespace std;


typedef int T;
struct lnode
{
	T data;
	lnode *next;
	lnode(const T& data=T()):data(data),next(NULL){}
};


typedef lnode* pNode;


class clist
{
	private :
		static pNode avail;
		static int cl_num;
		pNode head;
		size_t size;
	public:
		clist():head(NULL), size(0){ ++clist::cl_num;}
		~clist(){
			cout<<__FUNCTION__<data<<" ";
				tmp=tmp->next;
			}
			cout<size=0;
	for(int i=0;iadd(orig[i]);
}


clist& clist::operator=(clist& rhs)
{
	this->removeAll(); //赋值函数对旧值处理
	this->size=0;
	for(int i=0;iadd(rhs[i]);
}


//返回值是第n个节点的地址引用-> 就是第n-1个节点的链域的引用
//n:0~size -> 有连个指针指向头节点,head 和 第 size-1的链域
// n=0 n=size 的返回值是相同的
pNode& clist::getNodePtr(const int& n) throw(const char*)
{
	if(n<0 || n>size) throw "超出节点范围";
	if(0==n) return head;
	pNode Ptr=head;
	for(int i=1;i<=n-1;++i) Ptr=Ptr->next;
	return Ptr->next;
}


// 在第n个节点前插入,就是修改第n-1个节点的链域
// 与单链表不同的一点只有在插入到第一个元素的时候,需要更新两个指针:
//		1)head 值 2) 最后一个元素的链域
void clist::insertAt(const T& data, const int& n) throw(const char*)
{
	if(n<0 || n>size) throw "超出节点范围";// n==size --> 追加到末尾
	pNode newNode = this->get_node(data);
	if(0==n) this->getNodePtr(size)=newNode;  //更新最后节点的链域
	pNode& ptr=getNodePtr(n); 
	newNode->next = ptr;
	ptr = newNode;	
	++this->size;
}


T& clist::operator[](const int& n) throw(const char*) //非const成员访问,并可以修改返回值
{
	if(n<0 || n>=size) throw "超出节点范围";
	return 	getNodePtr(n)->data;
}


void clist::add(const T& data)
{
	this->insertAt(data, this->size);
}	


//释放节点,返回给avail(回收空间)
//回收一个节点,只要把节点查到类的静态链 avail头部就行了
void clist::removeAt(const int&n) throw(const char*)
{
	if(n<0 || n>=size) throw "超出节点范围"; 
	pNode& ptr=getNodePtr(n);
	pNode tmp=ptr;
	ptr=ptr->next;
	tmp->next=avail;
	avail=tmp;
}


// 用于释放avail的空间 <-- 已申请的节点真正的释放
// 当没有链表存在的时候,就释放类静态空间的可利用空间
void clist::removeFrom(pNode& ptr)
{
	cout<<"real delete clist!"<next;	
		delete[] tmp;
		tmp=ptr;
	}
	//过程中把avail置为NULL
}


const int clist::find(const T& data, const int& startN) throw(const char*)
{
	if(startN<0 ||startN>=size)  return -1;
	pNode ptr = getNodePtr(startN);
	int i=startN;
	while(ptr){
		if(data==ptr->data) return i;
		ptr=ptr->next;
		++i;
		if(ptr==head) break;
	}
	return -1;
}


//删除某条循环链表,就是把它回收到avail中
//只需注意两点:被回收的链表第一个节点的链域
//				指向avail; 而把avail值替换为
//				回收链表中第二个节点的首地址
void clist::removeAll()
{
	if(!head) return;
	pNode tmp=head->next;
	head->next=clist::avail;
	clist::avail=tmp;	
	head=NULL; //链表为空
	size=0; //error1
}


void clist::travel()
{
	pNode ptr=head;
	while(ptr)
	{
		cout<data<<" ";
		ptr=ptr->next;
		if(ptr==head) break;
	}
	cout<data<<" ";
		ptr=ptr->next;
		if(ptr==cl.head) break;
	}
	return os;
}


pNode clist::get_node(const T& data)
{
	if(!clist::avail) return new lnode(data);
	avail->data=data;	
	pNode rNode=avail;
	avail=avail->next;
	return rNode;
}

测试:
#include "clist.h"

int main()
{
	try{
		clist cl1;
		cl1.add(1);
		cl1.add(2);
		cl1.add(3);
		cout<<"cl1.find(1):"<

你可能感兴趣的:(数据结构)