参考博客
浅谈算法和数据结构——栈和队列
队列:先入先出
栈:后入先出
队列的实现:
队列的入队和出队:
入队需要添加一个新的元素,出队需要删除第一个元素。
因此需要一个索引来指出起点。但是只用一个指针来实现队列的入队的和出队,在空间有限时,实现起来容易造成空间资源的浪费。
如:
因为删除队列头,其实是将头指针后移,所以此时,队尾想进元素也是进不来的,就会有空间的浪费。
循环队列:
因此,更有效的方法是使用循环队列。 具体来说,我们可以使用固定大小的数组和两个指针来指示起始位置和结束位置。 目的是重用我们之前提到的被浪费的存储。
下面是循环队列的实现:
class MyCircularQueue {
private:
int *data=NULL;
int head = -1;
int tail = -1;
int size;
public:
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue(int k) {
data = new int[k];
size = k;
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool enQueue(int value) {
if(isFull())return false;
if(isEmpty())head=0;
tail=(tail+1)%size;//可以实现循环
data[tail]=value;
return true;
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
bool deQueue() {
if(isEmpty())return false;
if(head==tail){
head=-1;
tail=-1;
return true;
}
head=(head+1)%size;
return true;
}
/** Get the front item from the queue. */
int Front() {
if(isEmpty())return -1;
return data[head];
}
/** Get the last item from the queue. */
int Rear() {
if(isEmpty())return -1;
return data[tail];
}
/** Checks whether the circular queue is empty or not. */
bool isEmpty() {
return head==-1;
}
/** Checks whether the circular queue is full or not. */
bool isFull() {
return ((tail+1)%size)==head;
}
};
队列的用法:
int main() {
// 1. Initialize a queue.
queue<int> q;//初始化队列
// 2. Push new element.
q.push(5);//入队
q.push(13);
q.push(8);
q.push(6);
// 3. Check if queue is empty.
if (q.empty()) {
cout << "Queue is empty!" << endl;
return 0;
}
// 4. Pop an element.
int p=q.pop();//出队 p指向pop出来的元素,然后指针指向下一个。
// 5. Get the first element.
cout << "The first element is: " << q.front() << endl;
// 6. Get the last element.
cout << "The last element is: " << q.back() << endl;
// 7. Get the size of the queue.
cout << "The size is: " << q.size() << endl;
}
队列和广度优先搜索:
广度优先算法主要解决 路径最短问题
主要有单向搜索和双向搜索。
详见
leetcode.200(岛屿数量)广度优先+深度优先+并查集
leetcode. 279(完全平方数)BFS+动态规划+四平方
leetcode.752(打开转盘锁) BFS
这三篇文章
栈的实现
栈主要是 后进先出原则
定义栈:
stack<int>name;
其他栈的使用与队列相似。
栈与深度优先搜索:
DFS实现
1。递归
1 每一次函数调用都会有一次返回.当程序 执行到某一级递归的结尾处时,它会转移到前一级递归继续执行.
2 递归函数中必须包含可以终止递归调用的语句。
3 递归函数中,位于递归调用语句后的语句的执行顺序和各个被调用函数的顺序相反.
4 即位于递归函数入口前的语句,从外往里执行;位于递归函数入口后面的语句,由里往外执行。
递归的使用:
参考文章:算法思想(一) 递归
一个递归算法必须有两个部分:初始情况和递归部分。