Download presentation
Presentation is loading. Please wait.
Published byDaniella Sanders Modified over 8 years ago
2
栈 栈的应用 栈的应用 队列 队列 优先队列 优先队列
3
a1a1 a2a2 a3a3 a4a4 a5a5 a6a6 插入 x i 删除 x j 插入 删除 栈 ( Stack )
4
栈和队列 都是特殊的线性表 限定性的线性表 操作受限的线性表
5
一、栈 限定只在表的一端访问的线性表 元素只能从栈顶插入和删除 先进后出 后进先出 例 羊肉串 子弹夹 货 栈
6
top top A B C D top A B C D 顺序栈的模型 top B A C D top C B A D D C B A C B A D top B A C D top A B C D top A B C D
7
top top A B C D top A B C D top B A C D top B A C D top A B C D top A B C D top A B D C top D A B C top C D A B
8
顺序栈 —— 栈类的顺序表示 #ifndef STACK_CLASS #define STACK_CLASS #include const int MaxStackSize = 50;
9
template class Stack { T stacklist[MaxStackSize]; int top; public: Stack (void); void Push (const T& item); T Pop (void); void ClearStack(void); T Peek (void) const; //gettop int StackEmpty(void) const; int StackFull(void) const; };
10
// initialize stack top. template Stack ::Stack (void) : top(-1) { }
11
// push item on the the stack template void Stack ::Push (const T& item) { // if stacklist is full, terminate the program if (top == MaxStackSize-1) { cerr << "Stack overflow!" << endl; exit(1); } // increment top and copy item to stacklist top++; stacklist[top] = item; }
12
// pop the stack and return the top element template T Stack ::Pop (void) { T temp; // if stack is empty, terminate the program if (top == -1) { cerr << "Attempt to pop an empty stack!" << endl; exit(1); } temp = stacklist[top]; // record the top element top--; return temp; }
13
// return the value at the top of the stack template T Stack ::Peek (void) const { // if the stack is empty, terminate the program if (top == -1) { cerr << "Attempt to peek at an empty stack!" << endl; exit(1); } return stacklist[top]; }
14
// test for an empty stack template int Stack ::StackEmpty(void) const { // return the logical value top == - 1 return top == -1; }
15
// test for a full stack template int Stack ::StackFull(void) const { // test the position of top return top == MaxStackSize-1; }
16
// clear all items from the stack template void Stack ::ClearStack(void) { top = -1; } #endif // STACK_CLASS
17
链栈 栈的链式表示
18
线性链表类的定义
19
#include "node.h" template class LinkedList { Node *front, *rear, *prevPtr, *currPtr; int size; int position; Node *GetNode(const T& item,Node *ptrNext=NULL); void FreeNode(Node *p); void CopyList(const LinkedList & L); public: LinkedList(void); LinkedList(const LinkedList & L); ~LinkedList(void); LinkedList & operator= (const LinkedList & L); int ListSize(void) const;
20
int ListEmpty(void) const; void Reset(int pos = 0); void Next(void); int EndOfList(void) const; int CurrentPosition(void) const; void InsertFront(const T& item); void InsertRear(const T& item); void InsertAt(const T& item); void InsertAfter(const T& item); T DeleteFront(void); void DeleteAt(void); T& Data(void); void ClearList(void); };
21
链栈类的定义 #ifndef STACK_CLASS #define STACK_CLASS #include #include "link.h"
22
template class Stack { LinkedList stackList; public: Stack(void); // constructor void Push(const T& item); T Pop(void); T Peek(void); int StackEmpty(void) const; void ClearStack(void); };
23
// constructor template Stack ::Stack(void) { }
24
// uses the LinkedList method // ClearList to clear the stack template void Stack ::ClearStack(void) { stackList.ClearList( ); }
25
// use the LinkedList method //InsertFront to push item template void Stack ::Push(const T& item) { stackList.InsertFront(item); }
26
// use the LinkedList method DeleteFront to pop stack template T Stack ::Pop(void) { // check for an empty linked list if (stackList.ListEmpty( )) { cerr << "Popping an empty stack" << endl; exit(1); } // delete first node and return its data value return stackList.DeleteFront( ); }
27
// returns the data value of the first first item on the stack template T Stack ::Peek(void) {// check for an empty linked list if (stackList.ListEmpty( )) { cerr << "Calling Peek for an empty stack" << endl; exit(1); } // reset to the front of linked list and return value stackList.Reset( ); return stackList.Data( ); }
28
// use the LinkedList method //ListEmpty to test for empty stack template int Stack ::StackEmpty(void) const { return stackList.ListEmpty( ); } #endif // STACK_CLASS
29
二、 栈的应用 回文验证 数制转换 表达式求值 括号匹配检验 行编辑程序 递归实现
30
回文验证 palindrome 回文的例子 dad madam sees madam im adam a man a plan a canal panama
31
#include #pragma hdrstop #include "astack.h" // creates a new string with all blank characters removed void Deblank(char *s, char *t) { // loop through expression until NULL character is found while(*s != NULL) {// if character is a non-blank, copy to new string if (*s != ' ') *t++ = *s; s++; // move to next character } *t = NULL; // append NULL to new string }
32
void main(void) { const int True = 1, False = 0; Stack S; // stack elements are characters char palstring[80], deblankstring[80], c; int i = 0 ; int ispalindrome = True; // assume string is a palindrome cin.getline(palstring,80,'\n'); // read in the full-line string // remove blanks from string and put result in deblankstring Deblank(palstring,deblankstring); // push the chars of deblanked expression on the stack
33
i = 0; while(deblankstring[i] != 0) { S.Push(deblankstring[i]); i++; } i = 0; while (!S.StackEmpty( )) { c = S.Pop( ); // get next character from stack if (c != deblankstring[i]) { ispalindrome = False; break; } i++; }
34
if (ispalindrome) cout << '\"' << palstring << '\"' << " is a palindrome" << endl; else cout << '\"' << palstring << '\"' << " is not a palindrome" << endl; }
35
/* madam im adam "madam im adam" is a palindrome a man a plan a canal panama "a man a plan a canal panama" is a palindrome palindrome "palindrome" is not a palindrome */
36
数制转换 输入十进制数, 以其他进制输出 #include #pragma hdrstop #include "astack.h" // print integer num in base B
37
void MultibaseOutput(long num, int B) { // stack holds base B digits left to right Stack S; // extract base B digits right to left and push on stack S do { S.Push(int(num % B)); // convert to int and push on stack num /= B; // remove right most digit } while (num != 0); // continue until all digits computed while (!S.StackEmpty( )) // flush the stack cout << S.Pop( ); }
38
void main(void) { long num; // decimal number int B; // base // read 3 positive numbers and the desired base 2 <= B <= 9 for(int i=0;i < 3;i++) { cout << "Enter non-negative decimal number and base " << "(2<=B<=9): "; cin >> num >> B; cout << num << " base " << B << " is "; MultibaseOutput(num, B); cout << endl; }
39
/* Enter non-negative decimal number and base (2<=B<=9): 72 4 72 base 4 is 1020 Enter non-negative decimal number and base (2<=B<=9): 53 2 53 base 2 is 110101 Enter non-negative decimal number and base (2<=B<=9): 3553 8 3553 base 8 is 6741 */
40
表达式求值 中缀表达式 a+b*c a+b*(c-d)+e/f (b*b-4*a*c)/(2*a) 后缀表达式 abc*+ abcd-*+ef/+ bb*4a*c*-2a*/
41
// 后缀表达式求值 //calc.h #include #pragma hdrstop enum Boolean {False, True}; #include "astack.h"
42
class Calculator {Stack S; // holds operands void Enter(double num); Boolean GetTwoOperands(double& opnd1, double& opnd2); void Compute(char op); public: Calculator(void); // evaluate an expression and clear calculator void Run(void); void Clear(void); };
43
// store data value on the stack void Calculator::Enter(double num) { S.Push(num); }
44
Boolean Calculator::GetTwoOperands( double& opnd1, double& opnd2) { if (S.StackEmpty( )) // check for presence of operand { cerr << "Missing operand!" << endl; return False; } opnd1 = S.Pop( ); // fetch right-hand operand if (S.StackEmpty()) { cerr << "Missing operand!" << endl; return False; } opnd2 = S.Pop( ); // fetch left-hand operand return True; }
45
void Calculator::Compute(char op) { Boolean result; double operand1, operand2; result = GetTwoOperands(operand1, operand2); if (result == True) switch(op) { case '+': S.Push(operand2+operand1); break; case '-': S.Push(operand2-operand1); break; case '*': S.Push(operand2*operand1); break; case '/': if (operand1 == 0.0) { cerr << "Divide by 0!" << endl; S.ClearStack( ); } else S.Push(operand2/operand1); break; case '^': S.Push(pow(operand2,operand1)); break; } else S.ClearStack( ); // error! clear calculator }
46
Calculator::Calculator(void) {}
47
void Calculator::Run(void) { char c; double newoperand; while(cin >> c, c != '=') // read until '=' (Quit) { switch(c) {case '+': case '-': case '*': case '/': case '^': Compute(c); break; default: // not operator, must be operand; put char back cin.putback(c); // read the operand and store it on the stack cin >> newoperand; Enter(newoperand);break; } } if (!S.StackEmpty( )) cout << S.Peek( ) << endl; }
48
void Calculator::Clear(void) { S.ClearStack( ); }
49
#include "calc.h" void main(void) { Calculator CALC; CALC.Run( ); }
50
/* 8 8 * 6 6 * +.5 ^ = 10 3 4 + * Missing operand! 3 4 + 8 * = 56 1 0 / = Divide by 0! */
51
中缀表达式求值 定义表达式等级 为表达式中每个元素赋一个等级 表达式的累计等级必须为 0 或 1 整个表达式的等级为 1 项等级 数 1 正负 + - 0 运算 + - * / 左右括号( ) 0
52
5+3*-6 读到负号时等级累计 -1 ,出错 5+3- 最后等级 0 ,出错
53
中缀表达式求值法 用两个栈:一个存放操作数 一个存放运算符 2+3-4*5= 3 2+ 操作数 读入 “-” 弹出两个 - 优先级与 + 相同 操作数运算得到结 运算符 弹出 + 果 6 入栈 6- 操作数运算符 “-” 入栈 5 4* 6- 操作数 4 入栈 5 入栈 “*” 优先级高于 “-” 运算符 “*” 入栈 20 6- 操作数 弹出 “*” 20 入栈 弹出 5 4 运算 运算符 20 6- 操作数 弹出 “-” -14 入栈 弹出 20 6 运算 运算符 -14 操作数弹出结果 -14 运算符
54
定义运算符优先级 icp 栈外优先级 in coming priority isp 栈内优先级 in stack priority 运算符 icpisp 等级 + -11 * /22 ( 3 0 ) 000
55
#ifndef INFIX_MATH_OPERATIONS #define INFIX_MATH_OPERATIONS // list of constants specifying specific error messages const int OperatorExpected = 0, OperandExpected = 1, MissingLeftParenthesis = 2, MissingRightParenthesis = 3, InvalidInput = 4; // labels designating the parentheses characters const char leftparenthesis = '(', rightparenthesis = ')';
56
// a class that handles operators on the operator stack class MathOperator { char op; int icp , isp; public: MathOperator(void); MathOperator(char ch); int operator>= (MathOperator a) const; void Evaluate (Stack &OperandStack); char GetOp(void); };
57
// default constructor MathOperator::MathOperator(void) {}
58
MathOperator::MathOperator(char ch) { op = ch; // assign operator switch(op) { case ‘+’: case ‘-’: icp = 1; isp = 1; break; case ‘*’: case ‘/’: icp = 2; isp = 2; break; case ‘(’: icp = 3; isp = -1; break; case ')': icp = 0; isp = 0; break; }
59
int MathOperator::operator>= (MathOperator a) const { return isp >= a.icp; }
60
void MathOperator::Evaluate ( Stack &OperandStack) { float operand1 = OperandStack.Pop( ); float operand2 = OperandStack.Pop( ); switch (op) // select operation { case '+' : OperandStack.Push(operand2 + operand1); break; case '-': OperandStack.Push(operand2 - operand1); break; case '*': OperandStack.Push(operand2 * operand1); break; case '/': OperandStack.Push(operand2 / operand1); break; } }
61
// return operator associated //with current object char MathOperator::GetOp(void) { return op; } #endif // INFIX_MATH_OPERATIONS
62
#include #include // used for function 'isdigit' #pragma hdrstop #include "stack.h" // include template-based stack class #include "mathop.h" // defines the MathOperator class // checks if character is an operator or parentheses
63
int isoperator(char ch) { if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(') return 1; else return 0; }
64
// checks if character is a // whitespace character int iswhitespace(char ch) { if (ch == ' ' || ch == '\t' || ch == '\n') return 1; else return 0; }
65
// error handling function void error(int n) { // table gives the different error messages static char *errormsgs[] = { "Operator expected", "Operand expected", "Missing left parenthesis", "Missing right parenthesis", "Invalid input"}; cerr << errormsgs[n] << endl; exit(1); }
66
void main(void) { Stack OperatorStack; Stack OperandStack; MathOperator opr1,opr2; int rank = 0; float number; char ch; // process the expression until '=' is read while (cin.get(ch) && ch != '=') { // ******** process a floating point operand ******* * if (isdigit(ch) || ch == '.') { cin.putback(ch); cin >> number; rank++; if (rank > 1) error(OperatorExpected); OperandStack.Push(number); }
67
// ********* process an operator ********** else if (isoperator(ch)) { if (ch != '(') rank--; if (rank < 0) error(OperandExpected); opr1 = MathOperator(ch); while(!OperatorStack.StackEmpty() && (opr2 = OperatorStack.Peek( )) >= opr1) { opr2 = OperatorStack.Pop(); opr2.Evaluate(OperandStack); } OperatorStack.Push(opr1); }
68
// ********* process an operator ********** else if (isoperator(ch)) { if (ch != '(') // rank of '(' is 0 rank--; if (rank < 0) error(OperandExpected); // build a MathOperator object holding current // operator. pop the operator stack and evaluate // as long as the operator on the top of the stack // has a precedence >= that of the current operator. // push the current operator on the operator stack opr1 = MathOperator(ch); while(!OperatorStack.StackEmpty() && (opr2 = OperatorStack.Peek()) >= opr1) { opr2 = OperatorStack.Pop(); opr2.Evaluate(OperandStack); } OperatorStack.Push(opr1); } // ********* process a right parenthesis ********** else if (ch == rightparenthesis) { opr1 = MathOperator(ch); while(!OperatorStack.StackEmpty( )&& (opr2 = OperatorStack.Peek( )) >=opr1) { opr2 = OperatorStack.Pop( ); opr2.Evaluate(OperandStack); } if(OperatorStack.StackEmpty( )) error(MissingLeftParenthesis); opr2 = OperatorStack.Pop( ); // get rid of '(' }
69
else if (!iswhitespace(ch)) error(InvalidInput);} if (rank != 1) error(OperandExpected); while (!OperatorStack.StackEmpty( )) { opr1 = OperatorStack.Pop( ); if (opr1.GetOp( ) == leftparenthesis) error(MissingRightParenthesis); opr1.Evaluate(OperandStack); } cout << "The value is " << OperandStack.Pop() << endl; }
70
/* 2.5 + 6/3 * 4 - 3 = The value is 7.5 (2 + 3.25) * 4 = The value is 21 (4 + 3) - 7) = Missing left parenthesis */
71
三、队列 允许一端插入另一端取出的线性表 先进先出 队尾 插入端 队头 取出端 ←a1a1 a2a2 a3a3 a4a4 a5a5 ← ←a2a2 a3a3 a4a4 a5a5 a6a6 ←
72
循环队列 a1a1 a2a2 a3a3 a4a4 a5a5 a3a3 a4a4 a5a5 a6a6 a7a7 a 8 a3a3 a4a4 a5a5 a6a6 a7a7 front rear a 0 front rear a 0 a 1 front rear a 0 a 1 a 2 a3 a3 front rear a 1 a 2 a3 a3 frontrear a3 a3 a4a4 a5a5 frontrear a3 a3 a4a4 a5a5 a6a6 frontrear a3 a3 a4a4 a5a5 a6a6 a 7 rear front a 8 a3 a3 a4a4 a5a5 a6a6 a 7 rearfront a 8 a 9 a3 a3 a4a4 a5a5 a6a6 a 7 rearfront
73
循环队列 --- 队列的顺序表示 #ifndef QUEUE_CLASS #define QUEUE_CLASS #include // maximum size of a queue list const int MaxQSize = 50;
74
template class Queue { int front, rear, count; T qlist[MaxQSize]; public: Queue (void); void QInsert(const T& item); T QDelete(void); void ClearQueue(void); T QFront(void) const; int QLength(void) const; int QEmpty(void) const; int QFull(void) const; };
75
// initialize queue front, rear, count template Queue ::Queue (void) : front(0), rear(0), count(0) {}
76
// insert item into the queue template void Queue ::QInsert (const T& item) { if (count == MaxQSize) { cerr << "Queue overflow!" << endl; exit(1); } count++; qlist[rear] = item; rear = (rear+1) % MaxQSize; }
77
// delete element from front of queue and return its value template T Queue ::QDelete(void) { T temp; if (count == 0) {cerr << "Deleting from an empty queue!" << endl; exit(1); } temp = qlist[front]; count--; front = (front+1) % MaxQSize; return temp; }
78
// return value of the first entry template T Queue ::QFront(void) const { return qlist[front]; }
79
// return number of queue elements template int Queue ::QLength(void) const { return count; }
80
// test for an empty queue template int Queue ::QEmpty(void) const { // return the logical value count == 0 return count == 0; }
81
// test for a full queue template int Queue::QFull(void) const { // return the logical value count == MaxQSize return count == MaxQSize; }
82
// clear the queue by resetting count, //front and rear to 0 void Queue::ClearQueue(void) { count = 0; front = 0; rear = 0; } #endif // QUEUE_CLASS
83
队列 Queue 类的链式定义 #ifndef QUEUE_CLASS #define QUEUE_CLASS #include #include "link.h"
84
template class Queue { LinkedList queueList; public: Queue(void); void QInsert(const T& elt); T QDelete(void); T QFront(void); int QLength(void) const; int QEmpty(void) const; void QClear(void); };
85
// constructor template Queue ::Queue(void) {}
86
// LinkedList method ListSize //returns length of list template int Queue ::QLength(void) const { return queueList.ListSize( ); }
87
// LinkedList method ListEmpty //tests for empty queue template int Queue ::QEmpty(void) const { return queueList.ListEmpty(); }
88
// LinkedList method ClearList //clears the queue template void Queue ::QClear(void) { queueList.ClearList( ); }
89
// LinkedList method InsertRear //inserts item at rear template void Queue ::QInsert(const T& elt) { queueList.InsertRear(elt); }
90
// LinkedList method DeleteFront // removes item from front template T Queue ::QDelete(void) { // test for an empty queue and terminate if true if (queueList.ListEmpty( )) { cerr << "Calling QDelete for an empty queue!" << endl; exit(1); } return queueList.DeleteFront( ); }
91
// return the data value from the first item in the queue template T Queue ::QFront(void) { if (queueList.ListEmpty()) { cerr << "Calling QFront for an empty queue!" << endl; exit(1); } // reset to front of the queue and return data queueList.Reset( ); return queueList.Data( ); } #endif // QUEUE_CLASS
92
队列的应用 windows 命令序列 打印命令序列 涉及排队的问题 基数排序
93
四、优先级队列 优先级最高的元素先出 Priority Queue
94
优先级队列 //apqueue.h #ifndef PRIORITYQUEUE_CLASS #define PRIORITYQUEUE_CLASS #include // maximum size of the priority queue array const int MaxPQSize = 50;
95
template class PQueue { int count; T pqlist[MaxPQSize]; public: PQueue (void); void PQInsert(const T& item); T PQDelete(void); void ClearPQ(void); int PQEmpty(void) const; int PQFull(void) const; int PQLength(void) const; };
96
// initialize priority queue count template PQueue ::PQueue (void) : count(0) {}
97
// insert item into the priority queue template void PQueue ::PQInsert (const T& item) { if (count == MaxPQSize) { cerr << "Priority queue overflow!" << endl; exit(1); } // place item at the rear of the list and increment count pqlist[count] = item; count++; }
98
template T PQueue ::PQDelete(void) { T min; int i, minindex = 0; if (count > 0) { min = pqlist[0]; for (i = 1; i < count; i++) if (pqlist[i] < min) { min = pqlist[i]; minindex = i; } pqlist[minindex] = pqlist[count-1]; count--; } else { cerr << "Deleting from an empty priority queue!" << endl; exit(1); } return min; }
99
// return number of list elements template int PQueue ::PQLength(void) const { return count; }
100
// test for an empty priority queue template int PQueue ::PQEmpty(void) const { return count == 0; }
101
// test for a full priority queue template int PQueue ::PQFull(void) const { return count == MaxPQSize; }
102
// clear the priority queue by resetting count to 0 template void PQueue ::ClearPQ(void) { count = 0; } #endif // PRIORITYQUEUE_CLASS
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.