数据结构之:栈与队列

最近在复习数据结构与算法,加上刚开始写博客,所以打算把复习的东西在博客上记录,这样也是方便以后的查看。

一、栈

说起栈,栈是一种后进先出(Last In First Out)的数据结构,简称LIFO。主要的操作是进站push和出栈pop(也叫压栈)。栈主要是在序列的一头进行操作:


所以一直觉得这是一个比较流氓的行为,怎么先排队的轮到后面才到它啊。但是流氓的地方正是它魅力的地方,栈得的应用非常的广泛,例如一些算术符号(){}[]这种对称符号的匹配,或者是深度优先搜索DFS,里面的数据结构都是用到的栈。而栈的实现也有好几种,可以用数组实现,也可以用链表来实现。接下来我把这两种方法的实现都贴出来,代码均有C++实现:

#include <iostream>

using namespace std;

template <class T>
class Stack {   //抽象的数据类型 
	public :
		void clear();            //清空栈 
		bool push(const T item); //压栈,并且返回是否成功 
		bool pop(T &item);       //出栈,返回操作是否成功 
		bool Top(T &item);       //返回栈顶元素 
		bool isEmpty();          //栈是否为空 
		bool isFull();           //栈是否已满
		int size();              //查看栈里有多少个元素 
};


template <class T>
class arrStack : public Stack<T> {
	private :
		int mSize;               //栈的大小 
		int top;                 //栈顶位置 
		T *stack;                //存放栈元素的数组
	
	public :
		//构造函数 
		arrStack() {
			top = -1;
		}
		arrStack(int size) {
			mSize = size;
			top = -1;
			stack = new T[mSize];
		}
		~arrStack() {
			delete []stack;
		}
		//清空栈 
		void clear() {
			top = -1;
		}
		bool push(const T item);
		bool pop(T &item);
		bool Top(T &item);
		bool isEmpty();
		bool isFull();
		int size();
};

//压栈,要注意判断上溢
template <class T>
bool arrStack<T>::push(const T item) {
	if (top == mSize - 1) {     //栈已经满了,返回失败 
		cout << "栈已满" << endl;
		return false;
	} else {
		stack[++top] = item;    //注意是先++, 再赋值
		return true;
	}
}
//出栈,需要注意判断下溢
template <class T>
bool arrStack<T>::pop(T &item) {
	if (top == -1) {            //栈为空,所以没有元素可出栈 
		cout << "栈为空" << endl;
		return false;
	} else {
		item = stack[top--];    //注意这里是先赋值,top再--
		return true;
	}
}
//返回栈顶元素
template <class T>
bool arrStack<T>::Top(T &item) {
	if (top == -1) {            //栈为空,所以没有元素返回 
		cout << "栈为空" << endl;
		return false;
	} else {
		item = stack[top];    //注意这里是先赋值,top再-- 
		return true;
	}
}

template <class T>
bool  arrStack<T>::isEmpty() {
	if (top == -1) {
		return true;
	}
	return false;
}

template <class T>
bool arrStack<T>::isFull() {
	if (top == mSize - 1) {
		return true;
	}
	return false;
}

template <class T>
int arrStack<T>::size() {
	return top + 1;
}
链表实现:

template <class T>
struct Link {
	Link *next;
	T item;
	Link(const T data, Link<T> *nextL) {
		item = data;
		next = nextL;
	}
};

template <class T>
class lnkStack : public Stack<T> {
	private :
		Link<T> *top;           //栈顶指针
		int size;               //保存元素个数
	public :
		//构造函数 
		lnkStack(int size) {
			top = NULL;
			this -> size = 0;
		}
		//析构函数,需要free所有节点 
		~lnkStack() {
			clear();
		}
		//以链表的头部为栈顶 
		bool push(const T item) {
			Link<T> *tmp = new Link<T> (item, top);
			top = tmp;
			size++;
			return true;
		}
		//出栈
		bool pop(T &item) {
			if (top == NULL) {
				cout << "栈为空" << endl;
				return false;
			}
			item = top -> item;
			Link<T> *temp = top;
			top = top -> next;
			delete temp;
			return true;
		}
		//返回栈顶元素
		bool Top(T &item) {
			if (top == NULL) {
				cout << "栈为空" << endl;
				return false;
			}
			item = top -> item;
			return true;
		}
		//清空
		void clear() {
			while (top != NULL) {
				Link<T> *tmp = top;
				top = top -> next;
				delete tmp;
			}
		}
		bool isEmpty() {
			return (top == NULL);
		}
};



二、队列
因为最近顺便把C++的一些语法也复习一下,所以写得有点点复杂,接下来讲讲队列,队列其实和栈有着类似的操作,但是队列是两头进行操作,是一种先进先出的数据结构。这个就没那么流氓了哈哈哈,就像去银行排队,先到的先进行业务一样,按照这个例子,队列可以有很多种,例如优先队列,就像银行的vip窗口,能直接插插队。队列的操作如下:


可以看出,队列要维护两个指针,一个是头,一个是尾。头部指针主要用于出队和获取队头信息,而尾部指针主要用于进队。队列也有很多应用,例如宽度优先搜索,MST等等。我直接贴上我以前写的一个用指针实现的队列的C++头文件:

#ifndef QUEUE1_H
#define QUEUE1_H

#include <iostream>

using namespace std;
enum Error_code {success, overflow, underflow};

template<class Queue_entry>
struct Node {
	Queue_entry data;
	Node *next;
	Node() {
		next = NULL;
	}
	Node(const Queue_entry d, Node *n = NULL) {
		data = d;
		next = n;
	}
};

template<class Queue_entry>
class Queue {
	public:
		Queue();
		bool empty();
		Error_code append(const Queue_entry &item);
		Error_code serve();
		Error_code retrieve(Queue_entry &item) const;
		~Queue() {
			while (! empty()) {
				serve();
			}
		}
		Queue(const Queue &original);
		void operator= (const Queue &original);
	protected:
		Node<Queue_entry> *front, *rear;
		int count;
};

template<class Queue_entry>
Queue<Queue_entry>::Queue() {
	front = NULL;
	rear = NULL;
	count = 0;
}

template<class Queue_entry>
bool Queue<Queue_entry>::empty() {
	if (rear == NULL) {
		return true;
	} else {
		return false;
	}
}

template<class Queue_entry>
Error_code Queue<Queue_entry>::append(const Queue_entry &item) {
	Node<Queue_entry> *new_rear = new Node<Queue_entry>(item);
	if (new_rear == NULL) {
		return overflow;
	}
	if (rear == NULL) {
		front = new_rear;
		rear = new_rear;
	} else {
		rear -> next = new_rear;
		rear = new_rear;
	}
	count++;
	return success;
}

template<class Queue_entry>
Error_code Queue<Queue_entry>::serve() {
	if (front == NULL) {
		return underflow;
	}
	Node<Queue_entry> *old_front = front;
	front = old_front -> next;
	if (front == NULL) {
		rear = NULL;
	}
	delete old_front;
	count--;
	return success;
}

template<class Queue_entry>
Error_code Queue<Queue_entry>::retrieve(Queue_entry &item) const{
	if (front == NULL) {
		return underflow;
	} else {
		item = front -> data;
		return success;
	}
}

#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值