[算法拾遗]栈和队列的实现


本文介绍两种高度相似的数据结构——栈(stack)和队列(queue)。


栈和队列均支持以下两种操作:

  1. 向其添加元素;
  2. 从中删除元素;
栈和队列的不同主要在于这两种操作的顺序不同,前者是后进先出,后者是先进先出。


此外,为了调试方便,我们还允许显示其中的元素。


要实现栈和队列,一般有两种方式:采用数组或者链表。


在C++中,数组大小是一定的,但是占用空间相对较少,而链表可以动态扩展其长度,但是比较耗空间,实际使用时可以根据需求自己选定。


以下是本人用C++编辑的代码:


基于数组的栈实现:


// Header file: stackBasedOnArray.h
// Implementation of a stack based on an array.
// Edited by Sunshy.
// Home page: http://blog.csdn.net/longyindiyi
// Weibo: @云端暮雪
// 2014.03.19

#ifndef STACKBASEDONARRAY_EDITED_BY_SUN
#define STACKBASEDONARRAY_EDITED_BY_SUN

#define INIT_STACKA_SIZE_EDITED_BY_SUN 100

#include <iostream>

template<class DATATYPE>
class stackBasedOnArray
{
private:
	unsigned int numberOfElements; // the size of stack
	unsigned int top; // the top index of the stack
	bool isSuccessIndex; // 
	DATATYPE *stack;  // elements of the stack

	void initStack()
	{
		stack = new DATATYPE[numberOfElements];
		for(unsigned int i = 0; i < numberOfElements; i ++)
		{
			stack[i] = 0;
		}
		isSuccessIndex = true;
		top = 0;
	}

public:

	// Constructor function: if user don't give any parameter, 
	// then the size of the stack is initialized to be INIT_STACKA_SIZE_EDITED_BY_SUM, 
	// which is defined above.
	stackBasedOnArray()
	{
		numberOfElements = INIT_STACKA_SIZE_EDITED_BY_SUN; 
		initStack();
	}
	
	// Constructor function with a initialized parameter
	// Input:
	// numberOfElementsGivenByUser - initialize the size of the stack.
	stackBasedOnArray(unsigned int numberOfElementsGivenByUser)
	{
		numberOfElements = numberOfElementsGivenByUser; 
		initStack();
	}

	// Deconstructor Function
	~stackBasedOnArray()
	{
		delete []stack;
	}

	// Function - To check if the stack is an empty one.
	// Returning a bool value.
	bool stackBasedOnArray::isEmpty()
	{
		if(top == 0)
			return true;
		else
			return false;
	}

	// Function - To check if the pop or push operation is successfully done.
	// Returning a bool value.
	// Note: This funciton works only if it is used right after a push or pop operation has been done. 
	bool stackBasedOnArray::isSuccess()
	{
		return isSuccessIndex;
	}

	// Function - To get the size of the stack.
	// Returning the size of the stack.
	unsigned int stackBasedOnArray::getSize()
	{
		return numberOfElements;
	}

	// Function - To get the useful size of the stack.
	// Returning the top index of the stack.
	unsigned int stackBasedOnArray::getTop()
	{
		return top;
	}

	// Funcion - To push a value into the stack.
	// Input:
	// userValue - the value you want to push to the stack.
	// Returning no value.
	void stackBasedOnArray::push(DATATYPE userValue)
	{
		isSuccessIndex = false;
		if(top >= numberOfElements)
		{
			return;
		}

		stack[top] = userValue;
		top ++;
		isSuccessIndex = true;
		return;
	}
	

	// Funcion - To pop a value from the stack.
	// Returning the value poped from the stack.
	DATATYPE stackBasedOnArray::pop()
	{
		isSuccessIndex = false;
		if(top == 0)
		{
			return false;
		}

		top --;
		isSuccessIndex = true;
		return true;
	}

	// Function - To print the message of the stack.
	void stackBasedOnArray::print()
	{
		if(isEmpty())
		{
			return;
		}

		std::cout<<'\n';
		std::cout<<"Stack:"<<'\n';
		std::cout <<"Maximum Size: "<<getSize()<<'\n';
		std::cout <<"Current Size: "<<getTop()<<'\n';
		std::cout <<"Values: "<<'\n';

		for(unsigned int i = 0; i < top; i++)
		{
			cout<<stack[i]<<'\t';
		}
		std::cout<<'\n';
		return;
	}
};

#endif


基于数组的队列实现:


// Header file: queueBasedOnArray.h
// Implementation of a queue based on an array.
// Edited by Sunshy.
// Home page: http://blog.csdn.net/longyindiyi
// Weibo: @云端暮雪
// 2014.03.19

#ifndef QUEUEBASEDONARRAY_EDITED_BY_SUN
#define QUEUEBASEDONARRAY_EDITED_BY_SUN

#define INIT_QUAEUEA_SIZE_EDITED_BY_SUN 100

#include <iostream>

template<class DATATYPE>
class queueBasedOnArray
{
private:

	unsigned int queueSize; // the size of queue
	unsigned int head; // the head of the queue
	unsigned int tail; // the tail of the queue
	bool isSuccessIndex; // 
	bool isFullIndex;
	DATATYPE *queue;  // elements of the queue

	// Initializing the queue in conduct function.
	void initQueue()
	{
		queue = new DATATYPE[queueSize];
		for(unsigned int i = 0; i < queueSize; i++)
		{
			queue[i] = 0;
		}
		isSuccessIndex = true;
		isFullIndex = false;
		head = 0;
		tail = 0;
	}

public:

	// Constructor function: if user don't give any parameter, 
	// then the size of the queue is initialized to be INIT_QUAEUEA_SIZE_EDITED_BY_SUN, 
	// which is defined above.
	queueBasedOnArray()
	{
		queueSize = INIT_QUAEUEA_SIZE_EDITED_BY_SUN; 
		initQueue();
	}
	
	// Constructor function with a initialized parameter
	// Input:
	// queueSizeGivenByUser - initialize the size of the queue.
	queueBasedOnArray(unsigned int queueSizeGivenByUser)
	{
		queueSize = queueSizeGivenByUser; 
		initQueue();
	}

	// Deconstructor Function
	~queueBasedOnArray()
	{
		delete []queue;
	}

	// Function - To check if the queue is an empty one.
	// Returning a bool value.
	bool queueBasedOnArray::isEmpty()
	{
		if(head == tail && isFullIndex == false)
			return true;
		else
			return false;
	}

	// Function - To check if the queue is an full one.
	// Returning a bool value.
	bool queueBasedOnArray::isFull()
	{
		return isFullIndex;
	}

	// Function - To check if the enqueue or dequeue operation is successfully done.
	// Returning a bool value.
	// Note: This funciton works only if it is used right after a enqueue or dequeue operation has been done. 
	bool queueBasedOnArray::isSuccess()
	{
		return isSuccessIndex;
	}

	// Function - To get the size of the queue.
	// Returning the size of the queue.
	unsigned int queueBasedOnArray::getSize()
	{
		return queueSize;
	}

	// Function - To get the useful size of the queue.
	// Returning the top index of the queue.
	unsigned int queueBasedOnArray::getUsedSize()
	{
		if(isEmpty())
			return 0;
		if(tail > head)
			return tail - head;
		else
			return queueSize - (head - tail);
	}

	// Funcion - To enqueue a value into the queue.
	// Input:
	// userValue - the value you want to enqueue to the queue.
	// Returning no value.
	void queueBasedOnArray::enqueue(DATATYPE userValue)
	{
		if(isFull())
		{
		    isSuccessIndex = false;
			return;
		}

		queue[tail] = userValue;

		if(tail == queueSize - 1)
			tail = 0;
		else
			tail ++;

		if(tail == head)
			isFullIndex = true;

		isSuccessIndex = true;
		return;
	}
	

	// Funcion - To dequeue a value from the queue.
	// Returning the value dequeued from the queue.
	DATATYPE queueBasedOnArray::dequeue()
	{
		if(isEmpty())
		{
			isSuccessIndex = false;
			return false;
		}

		if(head == queueSize - 1)
			head = 0;
		else
			head ++;

		isFullIndex = false;

		isSuccessIndex = true;
		return true;
	}

	// Function - To print the message of the queue.
	void queueBasedOnArray::print()
	{
		if(isEmpty())
		{
			std::cout<<'\n';
			std::cout<<"Queue:"<<'\n';
			std::cout <<"Maximum Size: "<<getSize()<<'\n';
			std::cout <<"Current Size: "<<getUsedSize()<<'\n';
			std::cout<<'\n';
			return;
		}

		std::cout<<'\n';
		std::cout<<"Queue:"<<'\n';
		std::cout <<"Maximum Size: "<<getSize()<<'\n';
		std::cout <<"Current Size: "<<getUsedSize()<<'\n';
		std::cout <<"Values: "<<'\n';

		for(unsigned int i = 0; i < getUsedSize(); i++)
		{
			if((head + i) < queueSize)
				cout<<queue[head + i]<<'\t';
			else
				cout<<queue[i - (queueSize - head)]<<'\t';
		}
		std::cout<<'\n';
		return;
	}
};

#endif


基于链表的栈实现:


// Header file: stackBasedOnSingleLinkList.h
// Implementation of a stack based on an single link list.
// Edited by Sunshy.
// Home page: http://blog.csdn.net/longyindiyi
// 2014.03.20
// Weibo: @云端暮雪

#ifndef STACKBASEDONSINGLELINKLIST_EDITED_BY_SUN
#define STACKBASEDONSINGLELINKLIST_EDITED_BY_SUN

#define INIT_STACKSLL_SIZE_EDITED_BY_SUN 100

#include <iostream>

template<class DATATYPE>
class stackBasedOnSingleLinkList
{
private:

	struct node
	{
		DATATYPE value;
		node *next;
	};

	unsigned int stackSize; // the size of stack
	unsigned int currentSize;
	bool isSuccessIndex;

	node *head;

public:

	// Constructor function: if user don't give any parameter, 
	// then the size of the stack is initialized to be INIT_STACKSLL_SIZE_EDITED_BY_SUN, 
	// which is defined above.
	stackBasedOnSingleLinkList()
	{
		head = NULL; 
		stackSize = INIT_STACKSLL_SIZE_EDITED_BY_SUN;
		currentSize = 0;
		isSuccessIndex = false;
	}
	
	// Constructor function with a initialized parameter
	// Input:
	// stackSizeGivenByUser - initialize the size of the stack.
	stackBasedOnSingleLinkList(unsigned int stackSizeGivenByUser)
	{
		head = NULL; 
		stackSize = stackSizeGivenByUser;
		currentSize = 0;
		isSuccessIndex = false;
	}

	// Deconstructor Function
	~stackBasedOnSingleLinkList()
	{
		while(!isEmpty())
		{
			pop();
		}
	}

	// Function - To check if the stack is an empty one.
	// Returning a bool value.
	bool stackBasedOnSingleLinkList::isEmpty()
	{
		return currentSize == 0;
	}

	// Function - To check if the pop or push operation is successfully done.
	// Returning a bool value.
	// Note: This funciton works only if it is used right after a push or pop operation has been done. 
	bool stackBasedOnSingleLinkList::isSuccess()
	{
		return isSuccessIndex;
	}

	// Function - To get the size of the stack.
	// Returning the size of the stack.
	unsigned int stackBasedOnSingleLinkList::getMaxSize()
	{
		return stackSize;
	}

	// Function - To get the useful size of the stack.
	// Returning the top index of the stack.
	unsigned int stackBasedOnSingleLinkList::getCurrentSize()
	{
		return currentSize;
	}

	// Funcion - To push a value into the stack.
	// Input:
	// userValue - the value you want to push to the stack.
	// Returning no value.
	void stackBasedOnSingleLinkList::push(DATATYPE userValue)
	{
		if(getCurrentSize() >= getMaxSize())
		{
			isSuccessIndex = false;
			return;
		}
		
		isSuccessIndex = true;
		if(head == NULL)
		{
			head = new node;
			head->value = userValue;
			head->next = NULL;
			currentSize++;
			return;
		}

		node *newNode = new node;

		newNode->value = userValue;
		newNode->next = head;
		head = newNode;
		currentSize++;

		newNode = NULL;
		delete newNode;

		return;
		/*newNode->next = usernode;*/
	}
	

	// Funcion - To pop a value from the stack.
	// Returning the value poped from the stack.
	DATATYPE stackBasedOnSingleLinkList::pop()
	{
		if(isEmpty())
		{
			isSuccessIndex = false;
			return NULL;
		}

		DATATYPE rel = head->value;

		node *newNode = new node;

		newNode = head->next;
		head = newNode;

		currentSize--;
		isSuccessIndex = true;

		newNode = NULL;
		delete newNode;

		return rel;
	}

	// Function - To print the message of the stack.
	void stackBasedOnSingleLinkList::print()
	{
		std::cout<<'\n';
		std::cout<<"Stack:"<<'\n';
		std::cout <<"Maximum Size: "<<getMaxSize()<<'\n';
		std::cout <<"Current Size: "<<getCurrentSize()<<'\n';
		std::cout <<"Values: "<<'\n';

		node *newNode = head;

		while(newNode != NULL)
		{
			std::cout<<newNode->value<<'\t';
			newNode = newNode->next;
		}
		std::cout<<'\n';

		newNode = NULL;
		delete newNode;
		return;
	}
};

#endif


基于链表的队列实现:


// Header file: stackBasedOnSingleLinkList.h
// Implementation of a stack based on an single link list.
// Edited by Sunshy.
// Home page: http://blog.csdn.net/longyindiyi
// Weibo: @云端暮雪
// 2014.03.20

#ifndef QUEUEBASEDONSINGLELINKLIST_EDITED_BY_SUN
#define QUEUEBASEDONSINGLELINKLIST_EDITED_BY_SUN

#define INIT_QUEUESLL_SIZE_EDITED_BY_SUN 100

#include <iostream>

template<class DATATYPE>
class queueBasedOnSingleLinkList
{
private:

	// Linklist node
	struct node
	{
		DATATYPE value;
		node *next;
	};

	unsigned int queueSize; // the maximum size of stack
	unsigned int currentSize; // the current size of stack
	bool isSuccessIndex;

	node *head;

public:

	// Constructor function: if user don't give any parameter, 
	// then the size of the queue is initialized to be INIT_QUEUESLL_SIZE_EDITED_BY_SUN, 
	// which is defined above.
	queueBasedOnSingleLinkList()
	{
		head = NULL; 
		queueSize = INIT_QUEUESLL_SIZE_EDITED_BY_SUN;
		currentSize = 0;
		isSuccessIndex = true;
	}
	
	// Constructor function with a initialized parameter
	// Input:
	// queueSizeGivenByUser - initialize the size of the queue.
	queueBasedOnSingleLinkList(unsigned int queueSizeGivenByUser)
	{
		head = NULL; 
		queueSize = queueSizeGivenByUser;
		currentSize = 0;
		isSuccessIndex = true;
	}

	// Deconstructor Function
	~queueBasedOnSingleLinkList()
	{
		while(!isEmpty())
		{
			dequeue();
		}
	}

	// Function - To check if the queue is an empty one.
	// Returning a bool value.
	bool queueBasedOnSingleLinkList::isEmpty()
	{
		return currentSize == 0;
	}
	
	// Function - To check if the enqueue or dequeue operation is successfully done.
	// Returning a bool value.
	// Note: This funciton works only if it is used right after a enqueue or dequeue operation has been done. 
	bool queueBasedOnSingleLinkList::isSuccess()
	{
		return isSuccessIndex;
	}

	// Function - To get the maximum size of the queue.
	// Returning the maximum size of the queue.
	unsigned int queueBasedOnSingleLinkList::getMaxSize()
	{
		return queueSize;
	}

	// Function - To get the useful size of the queue.
	// Returning the current size of the queue.
	unsigned int queueBasedOnSingleLinkList::getCurrentSize()
	{
		return currentSize;
	}

	// Funcion - To enqueue a value into the queue.
	// Input:
	// userValue - the value you want to enqueue to the queue.
	// Returning no value.
	void queueBasedOnSingleLinkList::enqueue(DATATYPE userValue)
	{
		if(getCurrentSize() >= getMaxSize())
		{
			isSuccessIndex = false;
			return;
		}
		
		isSuccessIndex = true;
		if(head == NULL)
		{
			head = new node;
			head->value = userValue;
			head->next = NULL;
			currentSize++;
			return;
		}

		node *newNode = new node;

		newNode->value = userValue;
		newNode->next = NULL;
		head->next = newNode;
		currentSize++;

		newNode = NULL;
		delete newNode;

		return;
	}
	

	// Funcion - To dequeue a value from the queue.
	// Returning the value dequeued from the queue.
	DATATYPE queueBasedOnSingleLinkList::dequeue()
	{
		if(isEmpty())
		{
			isSuccessIndex = false;
			return NULL;
		}

		DATATYPE rel = head->value;

		node *newNode = new node;

		newNode = head->next;
		head = newNode;

		currentSize--;
		isSuccessIndex = true;

		newNode = NULL;
		delete newNode;

		return rel;
	}

	// Function - To print the message of the queue.
	void queueBasedOnSingleLinkList::print()
	{
		std::cout<<'\n';
		std::cout<<"Queue:"<<'\n';
		std::cout <<"Maximum Size: "<<getMaxSize()<<'\n';
		std::cout <<"Current Size: "<<getCurrentSize()<<'\n';
		std::cout <<"Values: "<<'\n';

		node *newNode = head;

		while(newNode != NULL)
		{
			std::cout<<newNode->value<<'\t';
			newNode = newNode->next;
		}
		std::cout<<'\n';

		newNode = NULL;
		delete newNode;
		return;
	}
};

#endif


以上代码仅供参考,本人测试可以正常工作。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值