160 likes | 301 Views
第四章 栈与队列. 熟练掌握 : 栈的定义、特性 栈的抽象数据类型、顺序表示、链表表示及相应操作 (特别注意栈空和栈满的条件) 队列的定义、特性 队列的抽象数据类型、顺序表示、链表表示及相应操作 (特别是循环队列中队头与队尾指针的变化情况). 掌握 : 优先队列的定义、特性 优先队列的的抽象数据类型 优先队列的插入与删除算法. 了解:在表达式计算时栈的使用, 主要 是中缀表示改为后缀表示的方法思路. 栈的定义及基本运算 栈 (Stack) 是限制在表的一端进行插入和删除运算的线性表,
E N D
第四章 栈与队列 • 熟练掌握: • 栈的定义、特性 • 栈的抽象数据类型、顺序表示、链表表示及相应操作 • (特别注意栈空和栈满的条件) • 队列的定义、特性 • 队列的抽象数据类型、顺序表示、链表表示及相应操作 • (特别是循环队列中队头与队尾指针的变化情况) • 掌握: • 优先队列的定义、特性 • 优先队列的的抽象数据类型 • 优先队列的插入与删除算法 了解:在表达式计算时栈的使用, 主要是中缀表示改为后缀表示的方法思路
栈的定义及基本运算 栈(Stack)是限制在表的一端进行插入和删除运算的线性表, 通常称插入、删除的这一端为栈顶(Top), 另一端为栈底(Bottom)。 当表中没有元素时称为空栈。 栈LIFO 假设栈S=(a1,a2,a3,…an), 则a1称为栈底元素,an为栈顶元素。 栈中元素按a1,a2,a3,…an的次序进栈,退栈按后进先出的原则进行的,因此an……a3 a2 a1的次序出栈。 进栈:top+1;新元素插入elements[top]位置, 出栈:top-1
栈的定义 P71-72 顺序栈——(数组存储) • 类定义 • 数据成员: int top; • Type *elements; • int maxSize; • 成员函数: GetTop( ) ——取栈顶元素 • IsEmpty( )——判断栈空(top==-1) • IsFull( ) ——判断栈满(top==maxSize-1) • MakeEmpty( )——清空栈 • √ void Push( ) ——元素进栈 (判断栈满) • √ int Pop( ) ——元素出栈 (判断栈空)
Push函数 P73 assert (!IsFull() ); //if (IsFull() ) 停止执行 top++; ① elements[top]=x; ② maxSize …… ① top X ② top X ……
Pop函数 if ( IsEmpty( ) ) return 0; top - - ; ① return 1; maxSize …… top X X ① top ……
链式栈——(链式存储) 用单链表表示栈时栈顶指针指向单链表的表头, 初始时为NULL 结点类定义: Type data; StackNode<Type> *link; 链式栈的类定义: 数据成员: StackNode<Type> * top; 成员函数: GetTop( ) ——取栈顶元素 IsEmpty( )——判断栈空(top==-1) IsFull( ) ——判断栈满(top==maxSize-1) MakeEmpty( )——清空栈 √ void Push( item ) ——元素进栈 (判断栈满) √ int Pop( ) ——元素出栈 (判断栈空)
Push ----进栈 P=new StackNode<Type>(item,top) Top=p; P75 p Pop----出栈 Top=top ->link; Delete p top
表达式的计算 算术表达式的三种表示: (1) 中缀:——例:a+b (2) 前缀:——例:+ab (3) 后缀:——例:ab+ 三种表达式之间的转换:按运算的优先次序全部加上括号, 逐个括号写成另一种表示式 ( 括号—— * ,/—— +,- ) 注意:字母出现的顺序不变
三种表达式之间的转换: 例1、将前缀表达式: ——转换成后缀表达式 (A+B)*D – E/(F +A*D)+C AB+ F AD* + AB+ D* E FAD*+ / AB+D* EFAD*+/ - AB+D* EFAD*+/ - C+ 例:A+B*D – E / F +A*D +C ABD*+EF/ - AD* + C+
4.3队列 FIFO 抽象数据类型队列的定义 队列(Queue)也是一种运算受限的线性表。它只允许在表的一端进行插入,而在另一端进行删除。允许删除的一端称为队头(front),允许插入的一端称为队尾(rear)。 假设队列S=(a1,a2,a3,…an), 则a1称为队首元素,an为队尾元素。 队中元素按a1,a2,a3,…an的次序入队,出队按先进先出的原则进行的,因此a1,a2,a3,…an的次序出队。 front 和rear的初始值地队列初始化时均应置为-1。 入队时将rear+1, 新元素插入elements[front]位置. 出队时,将加front+1, 删去元素,
0 1 2 3 0 1 2 3 Front rear Front rear (a)队列初始为空 (b)A,B,C入队 0 1 2 3 0 1 2 3 front rear front rear (c) a出队(d) b,c出队,队为空
队列的顺序表示和实现 顺序表示 长度:maxSize elements …… 入队:rear+1; elements[rear]=item 出队:front+1; rear …… front 进队要判队满 出队要判队空 队满:rear=maxSize - 1; 队空:rear=front;
循环队列的顺序表示和实现 —— front对应位置无元素 2 1 rear 队空:rear = front; 队满:(rear+1) % maxSize=front; 0 front …… maxSize 2 入队: rear=(rear+1) % MaxSize; elements[rear]=item 出队:front=(front+1)%MaxSize; 1 0 front …… rear
链表表示 P86 用单链表表示队列时队头指向单链表的第一个结点、队尾指针指向单链表的最后一个结点;初始时都为NULL rear rear 入队:p=new QueueNode<Type> (item, NULL); rear ->link=p; rear=p; front 入队不用考虑队满 但出队要考虑队空 出队:p=front; front=front ->link; delete p;
优先队列 ——每次取出的是具有最高优先权的元素。 (可理解为从大到小排列的顺序队列) 顺序存储 入队:j=count-1; // count表示元素个数 while (j>=0)&&(pqelements[j]>item) //找位置 { pqelements[j+1] = pqelements[j]; //后移一位 j ——; } pqelements[j+1]=item; count++;
出队: for (j=1 ; j< count; j++) pqelements[j-1]= pqelements[j]; //往前移 count ——; 习题:P92 4-1、4-5、4-9、4-10、4-11 附加: 4-2,4-3,4-7,4-12,4-13,4-14,4-15