1.这一章学习了两种新的结构,栈和队列,栈是后进先出的结构,队列是先进先出的结构,两种结构的特点决定了两种结构使用的场景。下面对栈和队列的一些基本操作进行展示。
(一)栈(分为顺序栈和链栈,这里是顺序栈的一些基本操作)
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 const int MAXSIZE = 100; //最大长度 6 7 typedef struct 8 { 9 char data[MAXSIZE]; 10 int top; //作为栈顶标志 11 int stackSize; //栈的最大容量 12 }SqStack; 13 14 void initStack(SqStack& s) //将栈初始化 15 { 16 s.top = 0; 17 s.stackSize = MAXSIZE; 18 } 19 20 void push(SqStack& s,char e) //将元素e入栈 21 { 22 s.data[s.top++] = e; 23 } 24 25 void pop(SqStack& s, char& e) //出栈一元素至e 26 { 27 e = s.data[--s.top]; 28 } 29 30 bool stackEmpty(SqStack s) //判断s是否栈空 31 { 32 if (s.top == 0) 33 { 34 return 1; 35 } 36 else 37 { 38 return 0; 39 } 40 } 41 42 bool stackFull(SqStack s) //判断s是否栈满 43 { 44 if (s.top == s.stackSize) 45 { 46 return 1; 47 } 48 else 49 { 50 return 0; 51 } 52 }
栈经常用于括号匹配,表达式求值。
(二)队列(分为顺序队和链队,这里是链队的一些基本操作)
1 typedef int QElemType; 2 typedef int Status; 3 typedef struct QNode 4 { 5 QElemType data; //数据域 6 struct QNode* next; //指针域 7 }QNode, * QueuePtr; 8 9 typedef struct 10 { 11 QueuePtr front; //队头指针 12 QueuePtr rear; //队尾指针 13 }LinkQueue; 14 15 Status InitQueue(LinkQueue& Q) 16 {//构造一个空队列 17 Q.front = Q.rear = new QNode; //生成新节点作为头节点,对头和队尾指针指向此节点 18 Q.front->next = NULL; //头指针的指针域置空 19 return 1; 20 } 21 22 Status EnQueue(LinkQueue& Q, QElemType e) 23 {//插入新元素e为Q的新队尾元素 24 QueuePtr p; 25 p = new QNode; //为新入队元素分配节点空间,用指针p指向 26 p->data = e; //将新结点的数据域置为e 27 Q.rear->next = p; 28 p->next = NULL; //将新节点插入至队尾 29 Q.rear = p; //修改队尾指针 30 return 1; 31 } 32 33 Status DeQueue(LinkQueue& Q,QElemType &e) 34 {//删除Q的队头元素 35 if (Q.front == Q.rear) return 0; //若队列空,则返回0 36 QueuePtr p; 37 p = Q.front->next; //p指向队头元素 38 e = p->data; //e保存队头元素的值 39 Q.front->next = p->next; //修改头指针 40 if (Q.rear == p) //最后一个元素被删,队尾指针指向头节点 41 { 42 Q.rear = Q.front; 43 } 44 delete p; //释放原队头元素的空间 45 return 1; 46 } 47 48 QElemType GetHead(LinkQueue Q) 49 {//返回Q的队头元素,不修改队头指针 50 if (Q.front != Q.rear) //队列非空 51 { 52 return Q.front->next->data; //返回队头元素的值,队头指针不变 53 } 54 }
队列常用于舞伴配对。
2.除了这两种结构外,我们还学习了递归的使用,下面这个是递归常见的一个例子:
题目:若有10级台阶,小白每次最多能跨3级,则小白登上这10级台阶一共有多少种方法?请给出具体的分析或计算过程。
1 /*思路 2 爬10级楼梯可以分为三种情况: 3 4 1)从9级楼梯爬1级 5 6 2)从8级楼梯爬2级 7 8 3)从7级楼梯爬3级 9 10 即 f (10) = f (9) + f (8) + f (7), 11 12 由此可以推出 f (n) = f (n-1) + f (n-2) + f (n-3) 13 14 当 n = 1时,只有一种走法:(1) 15 16 当 n = 2时,共有两种走法:(1,1)、(2,0) 17 18 当 n = 3时,共有三种走法:(1,1,1)、(1,2,0)、(2,1,0)、(3,0,0) 19 20 所以,f (4) = f (3) + f (2) + f (1) = 4 + 2 + 1 = 7; 21 22 f (5) = f (4) + f (3) + f (2) = 7 + 4 + 2 = 13; 23 24 f (6) = f (5) + f (4) + f (3) = 13 + 7 + 4 = 24; 25 26 f (7) = f (6) + f (5) + f (4) = 24 + 13 + 7 = 44; 27 28 f (8) = f (7) + f (6) + f (5) = 44 + 24 + 13 = 81; 29 30 f (9) = f (8) + f (7) + f (6) = 81 + 44 + 24 = 149; 31 32 f (10) = f (9) + f (8) + f (7) = 149 + 81 + 44 = 274; 33 */ 34 35 #include <iostream> 36 int f(int n) 37 { 38 if(n==1) return 1; 39 else if(n==2) return 2; 40 else if(n==3) return 4; 41 else return (f(n-1)+f(n-2)+f(n-3)); 42 } 43 using namespace std; 44 int main () 45 { 46 int n; 47 cin >> n; 48 cout << f(n); 49 return 0; 50 }
3.我们进行了一次小组合作打代码,开始pta一直显示运行超时,后来经过思考和修改,找到了错误在的地方,在这里放出来,希望自己和同学下次可以注意
1 int m,temp=0; 2 cin >> m; 3 string snum; 4 for(int i=0;i<m;i++) 5 { 6 cin>> snum; 7 for(int j=temp;j<a.length;j++) 8 { 9 if(snum==a.cus[j].num){ 10 cin >> a.cus[j].integral; 11 temp=j; 12 break; 13 } 14 } 15 }
这里题目规定了输入是升序的,所以每次查找时可以从上次查找的地方往后查,不需要重头开始,这样可以省下很多时间。
4.经过几周的学习,感觉自己现在可以脱离书本打一些代码了,并且懂得去思考如何降低时间复杂度。
5.希望以后的代码可以少一些错误,在打的时候就考虑到时间复杂度和空间复杂度,把已经学了的结构的基本操作记熟。