数据结构第三章学习小结
在第三章里学习了栈和队列两种结构: 因为之前已经基本了解过这些知识点,所以学起来其实比第二章要好一点,就是链队因为和上一张的“链表”有一点相似,花了点时间了解。
1. 首先是作业代码:括号匹配(里面包含了栈的基本操作函数)
这个代码是还没看老师的视频前参考书本打的,用了switch语句,一开始时输入样例代码没有采用getline,无法读入空格等其他字符,然后在经过网上搜索后,才知道要用getline进行输入=。=
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 #define MAXSIZE 101 5 typedef int SElemType; 6 typedef int Status; 7 typedef struct 8 { 9 SElemType *base; 10 SElemType *top; 11 int stacksize; 12 }SqStack; 13 14 Status InitStack(SqStack &S) 15 { 16 S.base = new SElemType[MAXSIZE]; 17 if (!S.base) return 0; 18 S.top = S.base; 19 S.stacksize = MAXSIZE; 20 return 1; 21 } 22 23 Status Push(SqStack &S, SElemType e) 24 { 25 if (S.top-S.base==S.stacksize) return 0; 26 *S.top++ = e; 27 return 1; 28 } 29 30 Status Pop(SqStack &S, SElemType e) 31 { 32 if (S.top-S.base==S.stacksize) return 0; 33 e = *--S.top; 34 return e; 35 } 36 37 SElemType GetTop(SqStack S) 38 { 39 if (S.top!=S.base) return *(S.top -1); 40 } 41 42 int main() 43 { 44 string a; 45 int flag=1, x; 46 SqStack S; 47 InitStack(S); 48 getline(cin,a); //可能会有空格,用getline可以读入空格; 49 for(int i=0;a[i]!='\0';i++) 50 { 51 switch(a[i]) 52 { 53 case '{': 54 Push(S,'{'); 55 break; 56 case '[': 57 Push(S,'['); 58 break; 59 case '(': 60 Push(S,'('); 61 break; 62 case '}': 63 if(GetTop(S)=='{') 64 Pop(S,x); 65 else flag=0; 66 break; 67 case ']': 68 if(GetTop(S)=='[') 69 Pop(S,x); 70 else flag=0; 71 break; 72 case ')': 73 if(GetTop(S)=='(') 74 Pop(S,x); 75 else flag=0; 76 break; 77 default: break; 78 } 79 } 80 if ((S.base==S.top)&&flag==1) 81 cout << "yes"; 82 else cout << "no"; 83 return 0; 84 }
第二个代码是看了老师的视频以后打的:(用flag标记,十分巧妙,看起来也比用switch语句要简洁,但是整体思路相差不大)
1 #include <iostream> 2 #include <cstring> 3 #define MAXSIZE 100 4 using namespace std; 5 typedef struct 6 { 7 char data[MAXSIZE]; 8 int top; 9 int Stacksize; 10 }Sqstack; 11 12 void Init(Sqstack &s) 13 {//初始化栈 14 s.top = 0; 15 s.Stacksize = MAXSIZE; 16 } 17 18 bool Stackfull(Sqstack s) 19 {//判断栈满 20 if(s.top==s.Stacksize) return true; 21 else return false; 22 } 23 24 bool Stackempty(Sqstack s) 25 {//判断栈空 26 if(s.top==0) return true; 27 else return false; 28 } 29 30 void push(Sqstack &s,char ch) 31 {//元素入栈 32 s.data[s.top++] = ch; 33 } 34 35 void pop(Sqstack &s,char &e) 36 {//元素出栈 37 e = s.data[--s.top]; 38 } 39 40 bool Matching(string str) 41 { 42 Sqstack s; 43 Init(s); 44 char e,ch; 45 int i=0,flag=1; 46 while(flag==1&&str[i]!='\0') 47 { 48 ch = str[i]; 49 if(ch=='('||ch=='['||ch=='{') 50 push(s,ch); 51 else if(ch==')'||ch==']'||ch=='}') 52 { 53 if(Stackfull(s)) flag=0; 54 else 55 { 56 pop(s,e); 57 if(ch==')'&&e!='(' 58 ||ch==']'&&e!='[' 59 ||ch=='}'&&e!='{') 60 flag = 0; 61 } 62 } 63 i++; 64 } 65 if(flag&&Stackempty(s)) return true; 66 else return false; 67 68 } 69 int main () 70 { 71 string str; 72 getline(cin,str); 73 if(Matching(str)) cout << "yes" <<endl; 74 else cout << "no" <<endl; 75 return 0; 76 }
2. 接下来就是实践一的代码了(内含队列的基本操作函数),这个代码花费的时间比较长,虽然整体打出来很快,但是最后输出有点小问题,然后花了比较长时间才找到了错误之处。一开始想的是用栈的方法,但是后来发现好像有点行不通,于是采取两个队列的方法会更简便。
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 #define MAXSIZE 1001 5 typedef int QElemType; 6 typedef int Status; 7 typedef struct //队列定义 8 { 9 QElemType *base; 10 int front; 11 int rear; 12 }SqQueue; 13 14 Status InitQueue (SqQueue &Q) 15 { 16 Q.base = new QElemType[MAXSIZE]; 17 if (!Q.base) return 0; 18 Q.front = Q.rear = 0; 19 return 1; 20 } 21 22 Status EnQueue(SqQueue &Q, QElemType &e) 23 { 24 if ((Q.rear +1)%MAXSIZE==Q.front) return 0; 25 Q.base[Q.rear] = e; 26 Q.rear = (Q.rear+1)%MAXSIZE; 27 return 1; 28 } 29 30 Status DeQueue(SqQueue &Q, QElemType &e) 31 { 32 if (Q.front == Q.rear) return 0; 33 e = Q.base[Q.front]; 34 Q.front = (Q.front+1)%MAXSIZE; 35 return e; 36 } 37 38 int QueueLength(SqQueue Q) 39 { 40 return (Q.rear-Q.front+MAXSIZE)%MAXSIZE; 41 } 42 43 QElemType GetHead(SqQueue Q) 44 { 45 if (Q.front!=Q.rear) 46 return Q.base[Q.front]; 47 } 48 49 bool EmptyQueue(SqQueue Q) 50 { 51 if (Q.front==Q.rear) return 0; //队列为空 52 else return 1; 53 } 54 55 void output (int a[], int n) 56 { 57 int i=1; 58 cout << a[0]; 59 for (;i<n;i++) 60 cout << " " << a[i]; 61 } 62 63 int main() 64 { 65 int e, N, a[MAXSIZE], b[MAXSIZE]; 66 int i=0, j=0; 67 SqQueue A, B; 68 InitQueue(B);//偶数B窗口,放B 69 InitQueue(A);//奇数A窗口,放A 70 cin >> N; 71 for (;i<N;i++) 72 { 73 cin >> a[i]; 74 if (a[i]%2==0) EnQueue(B, a[i]); 75 else EnQueue(A, a[i]); 76 } 77 while ((A.front!=A.rear)&&(B.front!=B.rear)) 78 { 79 DeQueue(A, e); //A是B的两倍 80 b[j++] = e; 81 DeQueue(A, e); 82 b[j++] = e; 83 DeQueue(B, e); 84 b[j++] = e; 85 } 86 while (A.front!=A.rear) 87 { 88 DeQueue (A, e); 89 b[j++] = e; 90 } 91 while (B.front!=B.rear) 92 { 93 DeQueue (B, e); 94 b[j++] = e; 95 } 96 output(b, N); 97 return 0; 98 }
总结: 通过以上的代码实践,和结合视频课本的知识,我感觉自己对栈和队列等等知识都已经有所掌握了,但是往往有时候还是很难发现代码中一下细小的错误点,所以还是实战得太少,经验不足,在下一章的学习中,我希望自己可以除了学习新知识以外,多去看看别人的相关代码,掌握更多种方法。其中我觉得CSDN社区就是一个很好的平台!里面有非常多的代码知识可以参考,但是有些可能会有错误,需要我们带着谨慎的眼光去看。