忙了几天来了吧,算法导论已经到第十章,以后会陆续讲课后习题和读书笔记写出来,后面的可能会比较详细一点。建议大家在第一遍看的时候对证明很多是可以略过的,但是也还是可以看得,建议基础不是很好的同学不要详细证明,能明白大题思路即可。以后可以再来详细看一遍。
1、栈和队列
<1>栈
(1概念)
栈可以说是一个操作受限的数组,他就像一个子弹夹,只能从口里面一颗一颗往里面装子弹,取出来的时候只能从开口处一颗一颗取出来,所以先装进去的会在下面,后装进去的会在上面,后装进去的先取出来,先装进去的后取出来。如下图所示:
当放子弹的时候,越来越靠外,当打出子弹的时候只有3出去了,2才能出去,最后1才能出去,所以就是先进后出,后进先出。
(2)基本函数实现
bool STACK_EMPTY(S){
if(S.top == -1) //我们默认从0开始存储,top指向的是
return true; //当前最顶端元素,如果没有就指向-1
else return false;
}
void PUSH(S,x){
if(s.top == n-1) //n-1表示的是栈的最大容量
printf("error")return ;
else {
S.top ++;
S[S.top] = x;
}
int POP(){
if(STACK_EMPTY(S)){
printf("error")return ;
}
return S[S.top--];
}
<2>队列
概念:
队列顾名思义就像排队的队伍一样,有一堆人排在一起,有第一个和最后一个(人数不为0),当然了只有一个人前后就重合了,人走从队头开始,人来在队尾排队,所以我们用front好人tail来标识相应的首尾。在队列中我们一般也别注意两种情形,队空和队满,标识队满一般有三种情形:
(1):设置一个标志tag,当每一次入队的时候,令tag = 1;当出队的时候,tag = 0;所以,如果在tag = 1后,Q.front = Q.rare,则说明是因为插队而引起的;反之,tag = 0时,Q.front = Q.rare,由此判断是队列空了;
(2):牺牲一个位置,当队列的总长为n时,当数据有n-1的时候我们说队列满。
(3):记录数据个数,使用一个计数变量记录下,数据的个数,当数据个数等于总长度的时候队满。
我们按照算法导论上的第一种方式处理,稍后后面两种的代码也会写出来。
(2)基本函数实现
//入队列:
void ENQUEUE(Q,x){
if(Q.head == (Q.tail+1)%n) { // n是队列可容纳最多元素个数
printf("error")return ;
}
Q[Q.tail++] = x;
Q.tail %= n;
}
//出队列
int DEQUEUE(Q){
if(Q.head == Q.tail){
printf("error")return INT_MIN;//我们返回int最小值
int x = Q[Q.head];
Q.head = (Q.head++)%n;
return x;
}