1 / 43

数据结构

数据结构. 第三章 栈和队列. 栈的定义 栈的存储结构及其运算的实现. 主要内容. 3.1.1 栈的定义. 一    什么是栈. 栈是限定仅能在表尾一端进行插入、删除操作的线性表. ( a 1 , a 2 , ... , a i -1 , a i , a i+1 , …, a n ). 删除. 插入. 第一个进栈的元素在 栈底 , 最后一个进栈的元素在 栈顶 , 第一个出栈的元素为 栈顶元素 , 最后一个出栈的元素为 栈底元素 。 不含元素的栈称为 空栈 。. 二 . 栈的逻辑结构. 进栈 Push. 出栈 Pop. 栈顶.

paxton
Download Presentation

数据结构

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 数据结构 第三章 栈和队列 第1页

  2. 栈的定义 栈的存储结构及其运算的实现 主要内容 第2页

  3. 3.1.1 栈的定义 一    什么是栈 栈是限定仅能在表尾一端进行插入、删除操作的线性表 (a1, a2, ... , ai -1, ai , ai+1, …, an) 删除 插入 第3页

  4. 第一个进栈的元素在栈底,最后一个进栈的元素在栈顶,第一个进栈的元素在栈底,最后一个进栈的元素在栈顶, 第一个出栈的元素为栈顶元素, 最后一个出栈的元素为栈底元素。 不含元素的栈称为空栈。 二.栈的逻辑结构 进栈 Push 出栈 Pop 栈顶 top 空栈 栈底 bottom top bottom 第4页

  5. top top top top top bottom top top top top top bottom 入栈与出栈 E E D D C C B B bottom A A A bottom E D C 出栈 B C D E 进栈 A进栈 栈操作图示 栈的特点 后进先出LIFO 第5页

  6. 思考:假设有A,B,C三个元素进S栈的顺序是A,B,C,写出所有可能的出栈序列。思考:假设有A,B,C三个元素进S栈的顺序是A,B,C,写出所有可能的出栈序列。 ABC BAC CAB ACB BCA CBA 第6页

  7. 如果是4个元素,那么它 不可能的出栈序列有哪些? • 不可能出现的出栈序列: • 2413 3124 • 3412 4123 • 4231 4213 • 4312 • 可能的出栈序列: • 1243 1324 1342 • 2134 2143 2314 • 2431 3241 3214 • 3421 4321 第7页

  8. 水平考试试题 栈是一种线性表,它的特点是A 。设用一维数组 A[1,…,n]来表示一个栈,令A[n]为栈底。用整型变量T指示当前栈顶位置,A[T]为栈顶元素。往栈中推入(PUSH)一个新元素时,变量T的值B ,从栈中弹出(POP)一个元素时,变量T的值C 。设栈空时,有输入序列a,b,c,经过PUSH,POP,PUSH,PUSH,POP操作后,从栈中弹出的元素序列是D ,变量T的值是E 。 A:1)先进先出 2)后进先出 3)进优于出 4)出优于进 5)随机进出 B、C:1)加1 2)减1 3)不变 4)清0 5)加2 6)减2 D:1)a,b 2)b,c 3)c,a 4)b,a 5)c,b 6)a,c E:1)n+1 2)n+2 3)n 4)n-1 5)n-2 第8页

  9. 水平考试试题 设有四个数据元素a1,a2,a3和a4,对它们进行栈操作。在进栈操作时,按a1、a2、a3、a4次序每次进入一个元素。假设栈的初始状态都是空。现要进行栈操作是进栈两次,出栈一次,再进栈两次,出栈一次;这时,第一次出栈得到的元素是A ,第二次出栈得到的元素是B 经操作后,最后在栈中的元素还有C 个。 供选择的答案 A:1)a1 2)a2 3)a3 4)a4 B:1)a1 2)a2 3)a3 4)a4 C:1)1 2)2 3)3 4)0 第9页

  10. 栈的特性 • 栈属于加了限制条件的线性结构; • 栈是后进先出的线性表; • 进栈和出栈只能从栈的一个端点进行; • 栈中的元素个数可以是0,此时是空栈; • 栈的元素的个数是可以变化的,可以是多个,但不能是无穷多个; • 每个栈中的元素的类型相同. 第10页

  11. 实现数制转换 实现函数的递归 行编辑:接受用户从终端输入的程序或数据,并存入用户的数据区 表达式求值:一个程序设计语言应该允许设计者根据需要用表达式描述计算过程,编译器则应该能分析表达式并计算出结果 栈的应用 Flash演示 第11页

  12. 初始化 IniStack(S): 构造一个空栈S,准备存放数据; 进栈操作 Push(S,x): 将数据元素x插入栈S,使x成为S的栈顶元素; 出栈操作 Pop(S): 当栈不空时返回栈顶元素为该函数的值,然后删除栈顶元素; 取栈顶元素 GetTop(S): 当栈不空时返回栈顶元素为该函数的值,但栈顶保持不变; 判栈空 EmptyStack(S): 若S为空栈则该函数值为1,否则为0。 三 栈的基本操作 第12页

  13. 3.1.2 栈的存储结构及其运算的实现 一、栈的顺序存储结构 用一个一维数组和一个整型变量来实现。 struct stack { datatype array[maxlen]; int top; } 栈数组 array[maxlen] 用来存放栈中所有元素; 整型变量top的整数值表示栈顶元素在数组array中的位置,也称为栈顶指针。 第13页

  14. MAX-1 n n-1 n-2 1 0 an an-1 a2 a1 top 当栈用顺序结构存储时, 栈的基本操作如建空栈、 进栈、出栈等操作 如何实现? ? 约定栈顶指针指向 向栈顶元素的位置 顺序栈的图示 栈空: Top=-1 栈满: Top=maxlen-1 第14页

  15. MAX-1 n n-1 n-2 1 0 top 建立空栈 1 ) 初始化栈 viod initstack(struct stack s ) { s.top=-1; } 第15页

  16. x an an-1 a2 a1 an an-1 a2 a1 MAX-1 n n-1 n-2 1 0 MAX-1 n n-1 n-2 1 0 top top x 进栈前 x 进栈后 • 2 ) 进栈操作 • viod Push ( struct stack s, datatype x ) • { • s.top=s.top+1; • s.array[top]=x; • } 第16页

  17. an an-1 a2 a1 an an-1 a2 a1 MAX-1 n n-1 n-2 1 0 MAX-1 n n-1 n-2 1 0 top top 出栈操作后 出栈操作前 • 3)出栈操作 • int pop( struct stack s ){ • return(array[s.top]) ; • s.top-- ; • } 第17页

  18. top MAX-1 n n-1 n-2 1 0 an an-1 a2 a1 MAX-1 n n-1 n-2 1 0 top • 栈在运算过程中可能发生“溢出”现象: • 上溢 • 下溢 第18页

  19. 2)进栈操作 • viod Push(struct stack s,datatype x ) • { • s.top=s.top+1; • s.array[top]=x; • } if (s.top=MAXlen-1) error(“栈满”) else { } 第19页

  20. 3)出栈操作 • int pop (struct stack s ){ • return(array[s.top]) ; • s.top--; • } if (s.top==-1) Error(“emptystack”); else { } 第20页

  21. 顺序栈的不足: • 存在栈满以后就不能再进栈的问题 • (这是因为用了定长的数组存储栈的元素) • 解决方法: • 使用链式存储结构。 第21页

  22. an Data next s 栈顶(单链表的表头) an-1 a1 栈底 二 、栈的链式存储和实现 栈的链式存储结构,也称链栈。其各结点的结构与单链表中的结点结构完全相同。如图所示: • 结点结构定义: • Typedef struct node • { elemtype data; • struct node *next; • }node,*pointer; 在前面学习了线性链表的插入删除操作算法,不难写出链式栈初始化、进栈、出栈等操作的算法 第22页

  23. s ^ (1) 初始化栈 Void initstack(pointer s) { s=null; } 第23页

  24. p s 栈顶 Data next an an an-1 an-1 Data next x s 栈顶 a1 栈底 a1 栈底 (2) 进栈 进栈前 进栈后 第24页

  25. 进栈算法 Void push(pointer s,datatype x) { p= (pointer *) malloc ( sizeof (node )); p->data=x; p->next=s->next; s->next=p; } 第25页

  26. an an x Data next an-1 an-1 p Data next s  栈顶 s 栈顶 a1 栈底 a1 栈底 (3) 出栈 出栈前 出栈后 第26页

  27. 出栈算法 Datatype pop ( pointer s ) { if (s->next==null) return(null); else { p=s->next; x=p->data; s->next=p->next; free(p); return(x); } } 第27页

  28. 3.2 队列 3.2.1 队列的定义 队列是限定仅能在表头进行删除,表尾进行插入的线性表 (a1, a2, ... , ai -1, ai , ai+1, …, an) 删除 插入 第28页

  29. 3.2 队列 队列的特点 先进先出 出队列 入队列 a1 a2 a3 ……an 队头 队尾 队 列 的 示 意 图 说明: 第一个入队的元素在队头,最后一个入队的元素在队尾, 第一个出队的元素为队头元素, 最后一个出队的元素为队尾元素 第29页

  30. 4 3 2 1 0 ? -1 又有J6入队, 怎么办? 3.2 队列 front,rear均为整数 用箭头指示只是为了直观 rear J5 J4 front J3 rear rear J2 J2 front J1 rear front front (d)J3,J4和J5相继入队之后,J2出队 (b)J1,J2相继入队列 (c)J1出队 (a)空队列 第30页

  31. 3.2 队列 3.2.2 队列的基本操作 1)初始化操作initQueue(Q):建立一个空队列Q,准备存放数据; 2)入队操作enQueue(Q,x):将数据x插入到队列Q的队尾,队列的长度加1;3)出队操作outQueue(Q):当队列为空时,返回队列头元素的值,同时删除队列头元素,队列的长度减1; 4)取队头元素操作GetQueue(Q):当队列为空时,返回队列头元素的值,但不删除队列头元素;5)判空操作:若队列为空,则返回的值为1,否则为0。 第31页

  32. 3.2.3 队列的存储结构及其基本运算的实现 1.链式存储结构 a1 a2 ∧ 3.2 队列 front 空链队列 ∧ rear front ∧ 链队列图示 struct node //链队列结点的类型定义{int data; struct node *link; };typedef struct node NODE NODE *front, *rear; 第32页

  33. Void addqlink(int x) {NODE *p; p=(NODE *)malloc(sizeof(NODE)); p->data=x;p->link=NULL; rear->link=p;rear=p; } 1) 进队列运算 3.2 队列 第33页

  34. NODE *deleqlink( ) { NODE *p; if (front==rear) return(NULL); p=front->link; front->link=p->link; if (front->link==NULL)rear=front; return(p); } 2) 出队列运算 3.2 队列 第34页

  35. 3.2 队列 3)队列的应用 1)解决计算机主机与外设不匹配的问题;2)解决由于多用户引起的资源竞争问题; 在操作系统课程中会讲到 3)离散事件的模拟----模拟实际应用中的各种排队现象;4)用于处理程序中具有先进先出特征的过程; 第35页

  36. 2.顺序存储结构 将front和rear两个整型变量作为c语言结构体的两个成员,该结构体定义如下: Struct sq_queue { Datatype data[maxlen]; Int front,rear; } 3.2 队列 1)初始化运算initqueue(struct sq_queue sq) 得到一个长度为maxsize的空队列sq, 此时sq->front=0;sq->rear=0. 第36页

  37. 2) 进队列运算enqueue(struct sq_queue sq,datatype x) sq->rear=sq->rear+1,sq->rear.data=x 3)出队列运算outqueue( struct sq_queue sq) sq->front=sq->front-1 4)读队列头元素运算gethead(struct sq_queue sq) 返回的函数值为sq->rear.data,sq队列没有改变 5)判断队列是否是空emptyqueue(struct sq_queue sq) 3.2 队列 第37页

  38. 3 1 2 rear front 5 5 4 0 4 0 3 1 3 1 rear 2 2 ? 5 如何判断循环队列 队空、队满? 4 0 front J6 J6 front J5 J7 J5 J8 J4 J4 rear J9 rear 3.2 队列 3 . 循环队列 J7 (c)队满 队空、队满 都有front=rear (b)队空 第38页

  39. J6 J5 J7 J8 J4 5 4 0 3 1 2 rear 3.2 队列 有两种方法:1)另设一个标志位以区分队空、队满。2)少用一个存储单元,队满条件:front=rear+1; front (d) 第39页

  40. rear front 5 4 0 3 1 2 3.2 队列 循环队列的基本操作算法 1)初始化操作 功能:建一个空队列Q; 算法: Int queue[MAX]; Int front, rear; int InitQueue_Sq() { //构造一个空队列Qfront = 0; rear=0; Return (1)} 建一个空队列Q 第40页

  41. 5 5 4 0 4 0 3 1 3 1 rear 2 2 rear J1 J1 J2 front J3 x J2 front J3 3.2 队列 2)入队操作功能:将元素 x 插入队尾 元素 x 入队前 元素 x 入队后 int insert_queue(int x) /*入队列*/ {if((rear+1)%MAX==front)return(0); rear=(rear+1)%MAX; queue[rear]=x;return(1); } 求余运算 第41页

  42. 5 5 J1 J1 4 0 4 0 3 1 3 1 rear rear J2 2 2 J2 front J3 J3 front 出队操作前 出队操作后 3.2 队列 3)出队操作功能:删除队头元素; int del_queue() /*出队列*/{ if(rear==front) return(0); front=(front+1)%MAX; return(queue[front]);} 第42页

  43. 小结和作业 • 作业: • 课后习题1、2、3 • 实训题: • 参见http://www.gdcp.cn/hjx/sjjg 第43页

More Related