技術的なやつ

技術的なやつ

1.3.2 動的確保のスタック・キューへの適用

//dynamic_stack
#include <iostream>

template <class T> class stack{
	class set_of_datum{
	private:
		T value;
		set_of_datum *next;
	public:
		set_of_datum(T value){
			this->value = value;
			next = NULL;
		}
		void set_next(set_of_datum *next){
			this->next = next;
		}
		set_of_datum *get_next(){return next;}
		T get_value(){return value;}
	};
private:
	set_of_datum *data; //スタックの本体
public:
	stack(); //コンストラクタ
	~stack(); //デストラクタ
	void clear(); //スタックの中身を空にする
	void push(T obj); //スタックにobjを追加する
	T pop(); //スタックからobjを取り出す
	void show(); //スタックの中身を見せる
	int get_data_num(); //スタックデータの数を返す
};

template <class T> stack<T>::stack(){
	data = NULL;
}

template <class T> stack<T>::~stack(){
	clear();
}

template <class T> void stack<T>::clear(){
	while(data != NULL){
		set_of_datum *target = data; //delete対象
		data = (*data).get_next();
		delete target;
	}
}

template <class T> void stack<T>::push(T obj){
	set_of_datum *new_datum = new set_of_datum(obj);
	(*new_datum).set_next(data);
	data = new_datum;
}

template <class T> T stack<T>::pop(){
	T dummy; //error発生時に返すダミーデータ
	if(data != NULL){
		T value = (*data).get_value();
		set_of_datum *target = data; //delete対象
		data = (*data).get_next();
		delete target;
		return value;
	}
	else{
		std::cout << "error: this stack is EMPTY! -- in stack<T>::pop()" << std::endl;
		return dummy;
	}
}

template <class T> void stack<T>::show(){
	set_of_datum *ptr = data; //表示するデータ
	for(int i=0; ptr!=NULL; i++){
		std::cout << i << ":" << (*ptr).get_value() << std::endl;
		ptr = (*ptr).get_next();
	}
}

template <class T> int stack<T>::get_data_num(){
	int value = 0;
	set_of_datum *ptr = data;
	while(ptr != NULL){
		value ++;
		ptr = (*ptr).get_next();
	}
	return value;
}

まぁ、こんなものだろう。
同様に、キューも。

//dynamic_queue
#include <iostream>

template <class T> class queue{
	class set_of_datum{
	private:
		T value;
		set_of_datum *before;
		set_of_datum *next;
	public:
		set_of_datum(T value){
			this->value = value;
			before = NULL;
			next = NULL;
		}
		void set_before(set_of_datum *before){
			this->before = before;
		}
		void set_next(set_of_datum *next){
			this->next = next;
		}
		set_of_datum *get_before(){return before;}
		set_of_datum *get_next(){return next;}
		T get_value(){return value;}
	};
private:
	set_of_datum *data; //キューの本体(先頭)
	set_of_datum *pop_target; //キューの本体(末尾)
public:
	queue(); //コンストラクタ
	~queue(); //デストラクタ
	void clear(); //キューの中身を空にする
	void enqueue(T obj); //キューにobjを追加する
	T dequeue(); //キューからobjを取り出す
	void show(); //キューの中身を見せる
	int get_data_num(); //キューのサイズを返す
};

template <class T> queue<T>::queue(){
	data = NULL;
	pop_target = NULL;
}

template <class T> queue<T>::~queue(){
	clear();
}

template <class T> void queue<T>::clear(){
	while(data != NULL){
		set_of_datum *target = data; //delete対象
		data = (*data).get_next();
		delete target;
	}
}

template <class T> void queue<T>::enqueue(T obj){
	set_of_datum *new_datum = new set_of_datum(obj);
	if(get_data_num() == 0)	pop_target = new_datum;
	else{
		(*new_datum).set_next(data);
		(*data).set_before(new_datum);
	}
	data = new_datum;
}

template <class T> T queue<T>::dequeue(){
	T dummy; //error発生時に返すダミーデータ
	if(data != NULL){
		T value = (*pop_target).get_value();
		set_of_datum *target = pop_target; //delete対象
		if(data == target)	data = NULL;
		else	(*(*target).get_before()).set_next(NULL);
		pop_target = (*target).get_before();
		delete target;
		return value;
	}
	else{
		std::cout << "This queue is EMPTY! -- error in queue<T>::pop()" << std::endl;
		return dummy;
	}
}

template <class T> void queue<T>::show(){
	set_of_datum *ptr = data;
	for(int i=0; ptr!=NULL; i++){
		std::cout << i << ":" << (*ptr).get_value() << std::endl;
		ptr = (*ptr).get_next();
	}
}

template <class T> int queue<T>::get_data_num(){
	int value = 0;
	set_of_datum *ptr = data;
	while(ptr != NULL){
		value++;
		ptr = (*ptr).get_next();
	}
	return value;
}

queue< T >::dequeue()のif文の中身が若干汚いけど、他に書き方はあるのだろうか。