您好,欢迎访问三七文档
第三章栈和队列栈和队列是两种特殊的线性表,是操作受限的线性表,称限定性DS§3.1栈(stack)栈的定义和特点定义:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈特点:先进后出(FILO)或后进先出(LIFO)ana1a2……...栈底栈顶...出栈进栈栈s=(a1,a2,……,an)只允许在一端插入和删除的线性表允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)特点后进先出(LIFO)栈(Stack)退栈进栈a0an-1an-2topbottom栈的存储结构顺序栈实现:一维数组s[M]top=0123450栈空栈顶指针top,指向实际栈顶后的空位置,初值为0top123450进栈Atop出栈栈满BCDEF设数组维数为Mtop=0,栈空,此时出栈,则下溢(underflow)top=M,栈满,此时入栈,则上溢(overflow)toptoptoptoptop123450ABCDEFtoptoptoptoptoptop栈空top空栈toptoptoptoptopa进栈b进栈aababcdee进栈abcdef进栈溢出abdee退栈ctopc退栈b退栈abaa退栈空栈topabdd退栈ctopabctoptop入栈算法0M-1栈1底栈1顶栈2底栈2顶出栈算法在一个程序中同时使用两个栈双栈共享一个栈空间b[0]t[0]t[1]b[1]0maxSize-1V栈的链接表示—链式栈链式栈无栈满问题,空间可扩充插入与删除仅在栈顶处执行链式栈的栈顶在链头适合于多栈操作top链栈栈顶^…...topdatalink栈底结点定义入栈算法出栈算法typedefstructnode{intdata;structnode*link;}JD;^…...栈底toptopxptop^…...栈底topq栈的应用过程的嵌套调用r主程序srrrs子过程1rst子过程2rst子过程3例递归的执行情况分析递归过程及其实现递归:函数直接或间接的调用自身叫~实现:建立递归工作栈voidprint(intw){inti;if(w!=0){print(w-1);for(i=1;i=w;++i)printf(“%3d,”,w);printf(“/n”);}}Ch3_10.c运行结果:1,2,2,3,3,3,递归调用执行情况如下:主程序(1)print(w)w=3;3print(2);(1)w=3top(2)输出:3,3,3w2print(1);(2)w=2(1)w=3top(3)输出:2,2w1print(0);(3)w=1(2)w=2(1)w=3top(4)输出:1w0(4)w=0(3)w=1(2)w=2(1)w=3topw(3)输出:2,2(2)2(1)3top(4)输出:1(3)1(2)2(1)3top(2)输出:3,3,3(1)3top返回(3)1(2)2(1)3top(4)0结束(1)TowerofHanoi问题问题描述:有A,B,C三个塔座,A上套有n个直径不同的圆盘,按直径从小到大叠放,形如宝塔,编号1,2,3……n。要求将n个圆盘从A移到C,叠放顺序不变,移动过程中遵循下列原则:每次只能移一个圆盘圆盘可在三个塔座上任意移动任何时刻,每个塔座上不能将大盘压到小盘上解决方法:n=1时,直接把圆盘从A移到Cn1时,先把上面n-1个圆盘从A移到B,然后将n号盘从A移到C,再将n-1个盘从B移到C。即把求解n个圆盘的Hanoi问题转化为求解n-1个圆盘的Hanoi问题,依次类推,直至转化成只有一个圆盘的Hanoi问题算法:执行情况:递归工作栈保存内容:形参n,x,y,z和返回地址返回地址用行编号表示nxyz返回地址main(){intm;printf(Inputnumberofdisks”);scanf(%d,&m);printf(”Steps:%3ddisks”,m);hanoi(m,'A','B','C');(0)}voidhanoi(intn,charx,chary,charz)(1){(2)if(n==1)(3)move(1,x,z);(4)else{(5)hanoi(n-1,x,z,y);(6)move(n,x,z);(7)hanoi(n-1,y,x,z);(8)}(9)}ABC1233ABC03ABC02ACB63ABC02ACB61ABC6ABC3ABC02ACB6main(){intm;printf(Inputthenumberofdisksscanf(%d,&m);printf(Thestepstomoving%3dhanoi(m,'A','B','C');(0)}voidhanoi(intn,charx,chary,charz)(1){(2)if(n==1)(3)move(1,x,z);(4)else{(5)hanoi(n-1,x,z,y);(6)move(n,x,z);(7)hanoi(n-1,y,x,z);(8)}(9)}ABC3ABC02ACB61CAB8ABC3ABC02ACB63ABC03ABC02ACB6main(){intm;printf(Inputthenumberofdisksscanf(%d,&m);printf(Thestepstomoving%3dhanoi(m,'A','B','C');(0)}voidhanoi(intn,charx,chary,charz)(1){(2)if(n==1)(3)move(1,x,z);(4)else{(5)hanoi(n-1,x,z,y);(6)move(n,x,z);(7)hanoi(n-1,y,x,z);(8)}(9)}ABC3ABC02BAC83ABC02BAC81BCA6ABC3ABC02BAC83ABC0main(){intm;printf(Inputthenumberofdisksscanf(%d,&m);printf(Thestepstomoving%3dhanoi(m,'A','B','C');(0)}voidhanoi(intn,charx,chary,charz)(1){(2)if(n==1)(3)move(1,x,z);(4)else{(5)hanoi(n-1,x,z,y);(6)move(n,x,z);(7)hanoi(n-1,y,x,z);(8)}(9)}ABC3ABC02BAC81ABC8ABC3ABC02BAC83ABC0栈空3ABC02BAC8Hanoi.cD:\fengyi\bkc\power\power.c回文游戏:顺读与逆读字符串一样(不含空格)dadtop1.读入字符串2.去掉空格(原串)3.压入栈4.原串字符与出栈字符依次比较若不等,非回文若直到栈空都相等,回文多进制输出:字符串:“madamimadam”例把十进制数159转换成八进制数(159)10=(237)81598198280237余7余3余2toptop7top73top732表达式求值中缀表达式后缀表达式(RPN)a*b+cab*c+a+b*cabc*+a+(b*c+d)/eabc*d+e/+中缀表达式:操作数栈和运算符栈例计算2+4-3*6操作数运算符24+操作数运算符6-操作数运算符6-36*操作数运算符6-18操作数运算符12后缀表达式求值步骤:1、读入表达式一个字符2、若是操作数,压入栈,转43、若是运算符,从栈中弹出2个数,将运算结果再压入栈4、若表达式输入完毕,栈顶即表达式值;若表达式未输入完,转1top4top43top735top例计算4+3*5后缀表达式:435*+top415top19(1)(2)(4)(5)(6)(7)(3)地图四染色问题R[7][7]12345671234567100001001111101010110101101011011001001100000000012345671223414334231#紫色2#黄色3#红色4#绿色§3.2队列队列的定义及特点定义:队列是限定只能在表的一端进行插入,在表的另一端进行删除的线性表队尾(rear)——允许插入的一端队头(front)——允许删除的一端队列特点:先进先出(FIFO)a1a2a3…………………….an入队出队frontrear队列Q=(a1,a2,……,an)双端队列a1a2a3…………………….an端1端2入队出队入队出队队列(Queue)定义队列是只允许在一端删除,在另一端插入的顺序表允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear)。特性先进先出(FIFO,FirstInFirstOut)a0a1a2an-1frontrear链队列结点定义typedefstructnode{intdata;structnode*link;}JD;头结点^…...front队头队尾rear设队首、队尾指针front和rear,front指向头结点,rear指向队尾队列的进队和出队frontrear空队列frontrearA进队AfrontrearB进队ABfrontrearC,D进队ABCDfrontrearA退队BCDfrontrearB退队CDfrontrearE,F,G进队CDEFGCDEFGfrontrearH进队,溢出队列的进队和出队原则进队时队尾指针先进一rear=rear+1,再将新元素按rear指示位置加入。出队时队头指针先进一front=front+1,再将下标为front的元素取出。队满时再进队将溢出出错;队空时再出队将队空处理。解决办法之一:将队列元素存放数组首尾相接,形成循环(环形)队列。frontrearx入队^xfrontreary入队x^yfrontrearx出队x^yfrontrear空队^frontreary出队^入队算法出队算法队列的顺序存储结构实现:用一维数组实现sq[M]front=-1rear=-1123450队空123450frontJ1,J1,J3入队J1J2J3rearrear123450J4,J5,J6入队J4J5J6front设两个指针front,rear,约定:rear指示队尾元素;front指示队头元素前一位置初值front=rear=-1空队列条件:front==rear入队列:sq[++rear]=x;出队列:x=sq[++front];rearrearfrontrear123450J1,J2,J3出队J1J2J3frontfrontfront存在问题设数组维数为M,则:当front=-1,rear=M-1时,再有元素入队发生溢出——真溢出当front-1,rear=M-1时,再有元素入队发生溢出——假溢出解决方案队首固定,每次出队剩余元素向下移动——浪费时间循环队列基本思想:把队列设想成环形,让sq[0]接在sq[M-1]之后,若rear+1==M,则令rear=0;0M-11frontrear实现:利用“模”运算入队:rear=(rear+1)%M;sq[rear]=x;出队:front=(front+1)%M;x=sq[front];队满、队空判定条件012345rearfrontJ4J5J6012345rearfrontJ9J8J7J4J5J6012345rearfront初始状态队空:front==rear队满:front==rear解决方案:1.另外设一个标志以区别队空、队满2.少用一个元素空间:队空:front==rear队满:(rear+1)%M==front队列存放数组被当作首尾相接的表处理。队头、队尾指针加1时从maxSize-1直接进到0,可用语言的取模(余数)运算实现。队头指针进1:front=(front+1)%maxSize;队尾指针进1:rear=(rear+1)%maxSize;队列初始化:front=rear=0;队空条件:front==rear;队
本文标题:高频与算法资料
链接地址:https://www.777doc.com/doc-3607972 .html