天天看點

C++類模闆實作雙連結清單

----------------------------------List.h------------------------------------

#ifndef LIST_H_XX
#define  LIST_H_XX

enum Error_code{rangeerror, underflow, overflow, success};
template<class Node_entry>
struct Node
{
	//data member
	Node_entry entry;
	Node<Node_entry> *next;
	Node<Node_entry> *back;
	//constructor
	Node();
	Node(Node_entry entry, Node<Node_entry> *next=NULL, Node<Node_entry>*back=NULL);
};

template<class List_entry>
class List
{
public:
	List();
	~List();
	List<List_entry>& operator = ( List<List_entry> ©);
	bool empty() const;
	Error_code replace(int position, const List_entry&data);
	Error_code retrieve(int position, List_entry&x) const;
	Error_code insert(int position, const List_entry&x);
	Error_code remove(int position);
	int getsize() const;
	void print() const;
protected:
	//mutable 的作用是在const函數中也可以對其進行修改
	int count;
	mutable int current_position;
	mutable Node<List_entry> *current;
	void set_position(int position) const;
};
#include "List.cpp"
#endif
           

------------------------------------------List.cpp-----------------------------------------------

#ifndef LIST_CPP_XX
#define LIST_CPP_XX
#include "List.h"
#include <iostream>
using namespace std;
//結構體構造函數
template <class Node_entry>
Node<Node_entry>::Node()
{
	back = next = NULL;
}
template <class Node_entry>
Node<Node_entry>::Node(Node_entry entry, Node<Node_entry> *next/* =NULL */, Node<Node_entry>*back/* =NULL */)
{
	this->entry = entry;
	this->back = back;
	this->next = next;
}
//類實作函數,constructor
template <class List_entry>
List<List_entry>::List()
{
	current_position = count = 0;
	current = NULL;
}
//destructor
template <class List_entry>
List<List_entry>::~List()
{
	while(!empty())
		remove(0);
}
//insert a member
//0<=position<=count
template <class List_entry>
Error_code List<List_entry>::insert(int position, const List_entry &x)
{
	if(position<0 || position>count)
		return rangeerror;
	Node<List_entry>*previous, *following, *new_node;
	if(position == 0)
	{
		//如果連結清單為空 
		if(count == 0) 
		{previous = following = NULL;}
		else
		{
			set_position(0);
			following = current;
			previous = NULL;
		}
	}
	else
	{
		set_position(position-1);
		previous = current;
		following = current->next;
	}
	//完成插入操作
	new_node = new Node<List_entry>(x, following, previous);
	if(new_node == NULL) return overflow;
	if(following!=NULL) following->back = new_node;
	if(previous!=NULL) previous->next = new_node;
	//指針指向目前操作的位置
	current = new_node;
	current_position = position;
	count++;
	return success;
}
//0<=position<coount
template <class List_entry>
Error_code List<List_entry>::remove(int position)
{
	Node<List_entry>* previous, *del_node, *following;
	if(empty())
		return underflow;
	if(position<0 || position>count)
		return rangeerror;
	set_position(position);
	if(position == 0)
	{	
		del_node = current;
		following = current->next;
		if(following!=NULL)following->back = NULL;
		delete del_node;

		count--;
		current = following;
		current_position = position;
		return success;		
	}
	else
	{
		del_node = current;
		following = current->next;
		previous = current->back;
		//斷開連接配接
		if(previous!=NULL)previous->next = following;
		if(following!=NULL)following->back = previous;
		//釋放記憶體
		delete del_node;
		count--;
		//如果删除的結點在最後
		if(following == NULL)
		{
			current_position = position-1;
			current = previous;
		}
		else
		{
			current = following;
			current_position = position;
		}
	}
	return success;
}
//current和current_position加了 mutable,是以這兩個變量在 const函數裡也能修改
template <class List_entry>
void List<List_entry>::set_position(int position) const
{
	int i ;
	if(position>current_position)
	{
		for(i=current_position; i<position; i++)
			current = current->next;
	}
	else
	{
		for(i=position; i<current_position; i++)
			current = current->back;
	}
	current_position = position;
}
//讀取指定位置的資料
//0<=position<count
template <class List_entry>
Error_code List<List_entry>::retrieve(int position, List_entry&x) const
{
	if(empty())
		return underflow;
	if(position<0 || position>count)
		return rangeerror;
	set_position(position);
	x = current->entry;
	return success;
}
//列印函數,注意不要在該函數中直接操作修改current 或調用 set_position
template <class List_entry>
void List<List_entry>::print() const
{
	List_entry x;
	int num = getsize();
	for(int i=0; i<num; i++)
	{
		retrieve(i, x);
		cout<<x;
	}
	cout<<endl;
}
//replace 函數
//0<=position<count
template <class List_entry>
Error_code List<List_entry>::replace(int position, const List_entry&data)
{
	if(empty())
		return underflow;
	if(position>count||position<0)
		return rangeerror;
	set_position(position);
	current->entry = data;
	return success;
}
template <class List_entry>
int List<List_entry>::getsize() const
{
	return count;
}

template <class List_entry>
bool List<List_entry>::empty() const
{
	return (count == 0);
}
//如果傳回值為void 那麼隻能實作單重指派,下面的方法可以實作多重指派如first_list=second_list=third_list
//另外要注意的是不能簡單地指派current和current_position,因為析構函數中會調用delete是以必須要在此處重新
//配置設定記憶體,即調用insert函數
template <class List_entry>
List<List_entry>&  List<List_entry>::operator=( List<List_entry> ©)
{
	int num = copy.getsize();
	List_entry data;
	for(int i=0; i<num; i++)
	{
		copy.retrieve(i, data);
		this->insert(i, data);
	}
	return *this;
}
#endif
           

--------------------------------- 測試代碼 -----------------------------------------------

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

int main()
{
	List<char*> tt;
	tt.insert(0, "mmsa ");
	tt.insert(1, "jjkl ");
	tt.insert(1, "ooks ");
  	tt.remove(0);
  	tt.print();
 	tt.insert(0, "nmcnv ");
 	tt.print();

 	List<char*> dd, mm;
 	mm = dd = tt;
	dd.replace(0, "dddd ");
 	dd.print();
	mm.print();
	system("pause");
	return 0;
}
           

------------------------- 測試截圖 ---------------------------

C++類模闆實作雙連結清單