数据结构:第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.上阶段的完成情况及后续目标:

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

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

你可能感兴趣的:(数据结构:第3章学习小结)