数据结构:第3章学习小结

1.内容小结:

栈(FILO)和队列(FIFO),是插入和删除限定在“端点”的线性表,都有顺序存储结构和链式存储结构。

1.1 栈:

栈的实现和基本操作:

 1 顺序栈: 
 2 #define MAXSIZE 100//栈存储空间可能的最大值 
 3 typedef struct{
 4     SElemType *base;//栈底指针
 5     SElemType *top; //栈顶指针
 6     int stacksize;  //栈可用的最大容量 
 7 }SqStack;
 8 
 9 Status InitStack(SqStack &s){
10     s.base = new SElemType[MAXSIZE];//为顺序栈分配一个最大容量
11     if(!s.base)        exit(OVERFLOW);     //存储空间分配失败 
12     s.top = s.base;                  //top初始化为base,空栈 
13     s.stacksize = MAXSIZE;             //stacksize设置为栈的最大容量
14     return OK; 
15 } 
16 
17 Status Push(SqStack &s, SElemType e){
18     if(s.top - s.base == s.stacksize){//栈满 
19         return ERROR;                
20     }
21     *s.top++ = e;                    //e(先)入栈,(后)栈顶指针加1 
22     return OK; 
23 }
24 
25 Status Pop(SqStack &s, SElemType &e){
26     if(s.top == s.base){            //栈空 
27         return ERROR;
28     }
29     e = *--s.top;                    //栈顶指针(先)减1,(后)栈顶元素赋给 e 
30 } 
31 
32 
33 链栈: 
34 typedef struct StackNode{
35     ElemType data;
36     StackNode *next;
37 }StackNode, *LinkStack;
38 
39 Status InitStack(LinkStack &s){//初始化空栈
40     s = NULL;
41     return OK;
42 } 
43 
44 Status Push(LinkStack &s, SElemType e){//考虑到栈FILO的特性,这里使用头插法添加新节点,且无需附加头节点 
45     StackNode *p = new StackNode;
46     p -> data = e;
47     p ->next = s;
48     s = p;
49     return OK;
50 } 
51 
52 Status Pop(LinkStack &s, SElemType &e){
53     if(s == NULL)    return ERROR;//栈空
54     e = s -> data;
55     StackNode *temp = s;
56     s = s -> next;
57     delete temp;                //释放原栈顶元素空间 
58     return OK;  
59 } 

栈的应用:

栈的应用有很多,这里要说的是递归。

利用栈和递归可以解决以下三类问题:

  • 定义是递归的,如打印Fibonacci数列,打印n的阶乘;
  • 数据结构是递归的,如本章所学的栈,以及后面要学习的广义表;
  • 问题的解法是递归的,如Hanoi塔问题。

递归的优点是很可观的,逻辑清晰,代码简洁。然而,递归往往会消耗大量的时间和空间,有时候还会有重复计算的问题。

1.2 队列

 

队列的实现和基本操作:

 1 顺序队列: 
 2 #define MAXSIZE 100                //队列可能的最大长度 
 3 typedef struct{
 4     QElemType *base;            //存储空间的基地址 
 5     int front;                    //头指针 
 6     int rear;                    //尾指针 
 7 }SqQueue; 
 8 
 9 Status IninQueue(SqQueue &q){    //初始化空队列 
10     q.base = new QElemType[MAXSIZE];
11     if(!q.base)        exit(OVERFLOW);        //存储空间分配失败 
12     q.front = q.rear = 0;                
13     return OK;
14 }
15 
16 Status Enter(SqQueue &q, QElemtype e){
17     if( (q.rear + 1) % MAXSIZE == q.front){//尾指针再循环意义上加1后等于头指针 
18         return ERROR;//队列已满 
19     }
20     q.base[q.rear] = e;                        //新元素插入队尾 
21     q.rear = (q.rear + 1) % MAXSIZE;        //队尾指针加1
22     return OK; 
23 } 
24 
25 Status Exit(SqQueue &q, QElemtype &e){
26     if(q.front == q.rear)    return ERROR;//队空 
27     e = q.base[q.front];
28     q.front = (q.front + 1) % MAXSIZE;//队头指针加1
29     return OK; 
30 }
31 
32 链式队列: 
33 typedef struct QNode{
34     QElemType data;
35     struct QNode *next;
36 }QNode;
37 typedef struct{
38     QNode *front;            //队头指针 
39     QNode *rear;            //队尾指针 
40 }LinkQueue;
41 
42 Status InitQueue(LinkQueue &q){
43     q.front = q.rear =  new QNode;    //队头队尾指针指向头节点 
44     q.front -> next = NULL;
45     return OK; 
46 } 
47 
48 Status Enter(LinkQueue &q, QElemType e){
49     QNode *p = new QNode;
50     p -> data = e;
51     p -> next = NULL;
52     q.rear -> next = p;    //将新元素节点插入队尾 
53     q.rear = p;//更新尾指针 
54     return OK;
55 }
56 
57 Status Exit(LinkQueue &q, QElemType &e){
58     if(q.front == q.rear)    return ERROR;//空队
59     QNode *p = q.front -> next;            //p指向队头元素
60     e = p -> data;
61     q.front -> next = p -> next;        //修改头节点的指针域 
62     if(q.rear == p)            q.rear = q.front;    //若出队的是最后一个元素,尾指针归位 
63     delete p;
64     return OK; 
65 } 

2.心得体会:

完成一道题目后,还要注重对时间和空间的考量,有时候题目即使没提示,也是可以通过一点小技巧节省时间和空间的。

3.资料推荐:

基础的知识可以看课本看mooc,也可以去社区或网站了解更多。

4.上阶段的完成情况及后续目标:

上阶段的目标是学好本章,基本完成,不足的是对递归还不熟悉。

后续目标当然是学好第四章啦,一步一个脚印。

posted on 2020-04-26 23:01  曾繁浩  阅读(229)  评论(0编辑  收藏  举报