栈的应用:数制转换
栈实现数制转换

return S->top==-1;
}
/*判栈满*/
int IsFull(SeqStack *S)
{
return S->top==StackSize-1;
}
/*进栈*/
void Push(SeqStack *S,DataType x)
{
if (IsFull(S))
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define StackSize 100 /*假定预分配的栈空间最多为100个元素*/
typedef int DataType;/*假定栈元素的数据类型为字符*/
typedef struct{
{
printf("栈上溢"); /*上溢,退出运行*/
exit(0);
}
S->data[++S->top]=x;/*栈顶指针加1后将x入栈*/
}
/*出栈*/
DataType Pop(SeqStack *S)
{
if(IsEmpty(S))
{ Байду номын сангаас
printf("栈为空"); /*下溢,退出运行*/
DataType data[StackSize];
int top;
}SeqStack;
/* 置栈空*/
void Initial(SeqStack *S)
{/*将顺序栈置空*/
S->top=-1;
栈的应用-数制转换(C语言数据结构)

栈的应⽤-数制转换(C语⾔数据结构)数制转换在计算机中经常⾯对不同数制的转换问题,如将⼀个⼗进制数N转换为d进制B。
数制转换的解决⽅法很多,其中⼀个简单的转换算法是重复下述两步。
直到N等于零为⽌。
x = N mod dN = N div d其中,N为需要转换的⼗进制数,d为转换后的进制,x值为转换后各个数位上的数,div为整除运算,mod为求余运算。
算法的运⾏过程为:第⼀次求出的x值为d进制数的最低位,最后⼀次求出的x值为d进制数的最⾼位,所以上述算法是从低位到⾼位顺序产⽣d进制的各位,然后逆序输出,因为它按“后进先出”的规律进⾏的,所以⽤栈这种结构处理最合适。
根据这个特点,利⽤栈来实现上述数制转换,即将计算过程种⼀次得到的d进制数码按顺序栈进栈。
计算结束后,再返顺序出栈,并按出栈顺序打印输出。
这样即可得到给定的⼗进制数对应的d进制数,由此可以得到数制转换的算法。
实现代码利⽤顺序栈实现数制转换(以⼗进制转换为⼆进制为例)1 #include <stdlib.h>2 #include <stdio.h>3 #define MAXSIZE 102445 /*定义顺序栈*/6 typedef int elemtype;7 typedef struct SequenStack8 {9 elemtype data[MAXSIZE];10 int top;11 }SequenStack;1213 /*判(顺序栈)栈空*/14 SequenStack * Init_SequenStack()15 {16 SequenStack * S;17 S = (SequenStack *)malloc(sizeof(SequenStack));1819 if (S == NULL)20 {21 return S;22 }23 S->top = -1;24 return S;25 }2627 /* 判空栈(顺序栈)*/28 int SequenStack_Empty(SequenStack * S)29 {30 if (S->top == -1)31 {32 return 1;33 }34 else35 {36 return 0;37 }38 }3940 /* ⼊栈(顺序栈) */41 int Push_SequenStack(SequenStack * S, elemtype x)42 {43 if (S->top >= MAXSIZE-1)44 {45 return 0;46 }47 S->top++;48 S->data[S->top] = x;49 return 1;50 }5152 /* 出栈(顺序栈) */53 int Pop_SequenStack(SequenStack * S, elemtype * x)54 {55 if (S->top == -1)56 {57 return 0;58 }59 else60 {61 S->top--;62 *x = S->data[S->top+1];63 return 1;64 }65 }6667 /* 进制转换算法 */68 void SequenStackConversion(int N)69 {70 int x;71 SequenStack * S = Init_SequenStack();72 while (N > 0)73 {74 Push_SequenStack(S, N % 2);75 N = N / 2;76 }77 while (! SequenStack_Empty(S))78 {79 Pop_SequenStack(S, &x);80 printf("%d", x);81 }82 }8384 int main()85 {86 int N;87 printf("Please enter the decimal number you want want to convert:\n");88 scanf("%d", &N);89 printf("The converted binary number is:\n");90 SequenStackConversion(N);91 }实现结果:利⽤链栈栈实现数制转换(以⼗进制转换为⼆进制为例)1 #include <stdio.h>2 #include <stdlib.h>34 /*定义链栈*/5 typedef int elemtype;6 typedef struct LinkedStackNode7 {8 elemtype data;9 struct LinkedStackNode *next;10 }LinkedStackNode, *LinkedStack;11 LinkedStack top;1213 /*链栈的初始化*/14 LinkedStack Init_LinkedStack()15 {16 LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));1718 if(top != NULL)19 {20 top->next = NULL;21 }22 return top;23 }2425 /*判栈空*/26 int LinkedStack_Empty(LinkedStack top)27 {28 if (top->next == NULL)29 {30 return 1;31 }32 else33 {34 return 0;35 }3637 }3839 /*⼊栈*/40 int Push_LinkedStack(LinkedStack top, elemtype x)41 {42 LinkedStackNode *node;43 node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));4445 if (node == NULL)46 {47 return 0;48 }49 else50 {51 node->data = x;52 node->next = top->next;53 top->next = node;54 return 1;55 }5657 }5859 /*出栈*/60 int Pop_LinkedStack(LinkedStack top, elemtype * x)61 {62 LinkedStackNode *node;63 if (top->next == NULL)64 {65 return 0;66 }67 else68 {69 node = top->next;70 *x = node->data;71 top->next = node->next;72 free(node);73 return 1;74 }7576 }7778 /*进制转换*/79 void ListStackConversion(int N)80 {81 int x;82 LinkedStack S = Init_LinkedStack();83 while (N > 0)84 {85 Push_LinkedStack(S, N % 2);86 N = N / 2;87 }88 while (! LinkedStack_Empty(S))89 {90 Pop_LinkedStack(S, &x);91 printf("%d", x);92 }9394 }9596 int main()97 {98 int N;99 printf("Please enter the decimal number you want want to convert:\n"); 100 scanf("%d", &N);101 printf("The converted binary number is:\n");102 ListStackConversion(N);103 }实现结果:把顺序栈和链栈两种功能综合在⼀起实现数制转换(以⼗进制转换为⼗六进制为例)1 /* 进制转换 */2 #include <stdlib.h>3 #include <stdio.h>4 #define MAXSIZE 100 /*定义顺序栈的长度*/56 /*定义顺序栈*/7 typedef int elemtype;8 typedef struct SequenStack9 {10 elemtype data[MAXSIZE];11 int top;12 }SequenStack;1314 /*定义链栈*/15 typedef int elemtype;16 typedef struct LinkedStackNode17 {18 elemtype data;19 struct LinkedStackNode *next;20 }LinkedStackNode, *LinkedStack;21 LinkedStack top;2223 /* 顺序栈初始化 */24 SequenStack * Init_SequenStack()25 {26 SequenStack * S;27 S = (SequenStack *)malloc(sizeof(SequenStack));2829 if (S == NULL)30 {31 return S;32 }33 S->top = -1;34 return S;35 }3637 /*链栈的初始化*/38 LinkedStack Init_LinkedStack()39 {40 LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));4142 if(top != NULL)43 {44 top->next = NULL;45 }46 return top;47 }4849 /*判栈(顺序栈)空*/50 int SequenStack_Empty(SequenStack * S)51 {52 if (S->top == -1)53 {54 return 1;55 }56 else57 {58 return 0;59 }60 }6162 /* 判栈(链栈)空 */63 int LinkedStack_Empty(LinkedStack top)65 if (top->next == NULL)66 {67 return 1;68 }69 else70 {71 return 0;72 }7374 }7576 /* ⼊栈(顺序栈)*/77 int Push_SequenStack(SequenStack * S, elemtype x)78 {79 if (S->top >= MAXSIZE-1)80 {81 return 0;82 }83 S->top++;84 S->data[S->top] = x;85 return 1;86 }8788 /* 出栈(顺序栈) */89 int Pop_SequenStack(SequenStack * S, elemtype * x)90 {91 if (S->top == -1)92 {93 return 0;94 }95 else96 {97 S->top--;98 *x = S->data[S->top+1];99 return 1;100 }101 }102103 /* ⼊栈(链栈) */104 int Push_LinkedStack(LinkedStack top, elemtype x)105 {106 LinkedStackNode *node;107 node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode)); 108109 if (node == NULL)110 {111 return 0;112 }113 else114 {115 node->data = x;116 node->next = top->next;117 top->next = node;118 return 1;119 }120121 }122123 /* 出栈(链栈) */124 int Pop_LinkedStack(LinkedStack top, elemtype * x)125 {126 LinkedStackNode *node;127 if (top->next == NULL)128 {129 return 0;130 }131 else132 {133 node = top->next;134 *x = node->data;135 top->next = node->next;136 free(node);137 return 1;138 }139140 }141142 /* 使⽤顺序⽅式进⾏进制转换的函数 */143 void SequenStackConversion(int N)144 {145 int x;146 SequenStack * S = Init_SequenStack();147 while (N > 0)149 Push_SequenStack(S, N % 16); 150 N = N / 16;151 }152 while (! SequenStack_Empty(S))153 {154 Pop_SequenStack(S, &x);155 switch (x)156 {157 case 10:158 printf("A");159 break;160 case 11:161 printf("B");162 break;163 case 12:164 printf("C");165 break;166 case 13:167 printf("D");168 break;169 case 14:170 printf("E");171 break;172 case 15:173 printf("F");174 break;175 default:176 printf("%d", x);177 break;178 }179 }180 }181182 /* 使⽤链栈⽅式进⾏进制转换的函数 */ 183 void ListStackConversion(int N)184 {185 int x;186 LinkedStack S = Init_LinkedStack(); 187 while (N > 0)188 {189 Push_LinkedStack(S, N % 16);190 N = N / 16;191 }192 while (! LinkedStack_Empty(S))193 {194 Pop_LinkedStack(S, &x);195 switch (x)196 {197 case 10:198 printf("A");199 break;200 case 11:201 printf("B");202 break;203 case 12:204 printf("C");205 break;206 case 13:207 printf("D");208 break;209 case 14:210 printf("E");211 break;212 case 15:213 printf("F");214 break;215 default:216 printf("%d", x);217 break;218 }219220 }221222 }223224 void function()225 {226 printf("-------------------------------------------\n"); 227 }228229 /* 主函数调⽤进制转换函数 */230 int main()231 {232 int N, x;233 printf("Please enter the decimal number you want want to convert:\n");234 scanf("%d", &N);235 function();236 printf("Choose using sequential stack or list stack\n");237 printf("1:Sequential stack 2:list stack:\n");238 function();239 scanf("%d", &x);240 printf("The converted binary number is:\n");241 switch (x)242 {243 case 1:244 SequenStackConversion(N);245 break;246 case 2:247 ListStackConversion(N);248 break;249 default:250 printf("error");251 break;252 }253254 return 0;255 }值得注意的是,当⼗进制转换为⼗六进制的时候,需要考虑输出现实⼤于9的⼗六进制位数,这⾥我们考虑可以使⽤switch开关实现。
数据结构实验报告 栈进制转换

数据结构实验报告栈进制转换数据结构实验报告栈进制转换一、实验目的栈是一种常见的数据结构,本实验的目的在于通过实现栈的基本操作,设计并实现一个进制转换的程序,并通过实验验证程序的正确性和效率。
二、实验原理1.栈的定义和基本操作栈是一种后进先出(Last In First Out,简称LIFO)的数据结构。
它可以通过一个指针来标识当前栈顶元素,栈顶指针top的起始值为-1,空栈时top=-1.2.栈的进制转换将一个十进制数转换为其他进制(如二进制、八进制、十六进制)的过程中,可以通过栈来实现。
具体步骤如下:- 初始化一个空栈;- 将十进制数依次除以目标进制的基数,将余数依次入栈,直到商为0;- 依次出栈,将出栈的余数组合起来,得到转换后的目标进制数。
三、实验内容1.实现栈的基本操作(1)定义栈结构,包括元素数组和栈顶指针;(2)实现入栈操作push(),将元素插入到栈顶;(3)实现出栈操作pop(),从栈顶删除一个元素并返回其值;(4)实现获取栈顶元素的操作getTop(),返回栈顶元素的值;(5)实现判断栈是否为空的操作isEmpty(),返回布尔值;(6)实现判断栈是否已满的操作isFull(),返回布尔值。
2.设计并实现进制转换的程序(1)初始化一个空栈用于存放转换后的数字;(2)输入十进制数num和目标进制target;(3)通过栈的操作将num转换为target进制数;(4)输出转换后的结果。
四、实验步骤1.实现栈的基本操作(1)定义栈的结构和相关操作;(2)编写相应的测试代码,验证栈的基本操作是否正确。
2.设计并实现进制转换的程序(1)根据原理部分的步骤,设计转换程序的具体逻辑;(2)编写相应的测试代码,验证转换程序的正确性和效率。
五、实验结果与分析1.给定一个十进制数num=12345,目标进制为二进制(target=2),经过进制转换后得到的结果为.111.2.给定一个十进制数num=456,目标进制为八进制(target=8),经过进制转换后得到的结果为.710.本实验的结果表明,转换程序能够正确地将十进制数转换为目标进制数,并且具有较高的效率。
栈的应用教学设计

出”。
四、栈的应用举例任何一个表达式都是由操作数、运算符和界限符组成的。
后两项统称为算符,算符集合命名为OP。
引入问题:如何用堆栈实现表达式求值?表达式求值有三种形式。
中缀表示:<操作数><运算符><操作数>前缀表示:<运算符><操作数><操作数>后缀表示:<操作数><操作数><运算符>以中缀表达式为例,进行重点讲解。
例2、用栈求解表达式21+44-3*6的值。
# 21+44-3*6#实现方法:设置一个运算符栈和一个操作数栈。
算符间的优先关系求值规则:1)先乘除,后加减;2)先括号内,后括号外;3)同类运算,从左至右。
约定:q1---栈顶的运算符q2---当前的运算符当q1=#,为开始符当q2=#,为结束符根据上述优先关系表,可见21+44-3*6#中‘-’ <‘*’,‘*’ >‘#’。
2、算法基本思想1)首先置‘#’为运算符栈的栈底元素, 操作数栈为空栈;2) 依次读入表达式中各个字符,如果判断为操作数则OPND栈,如21,44,进操作数栈;若为运算符θ2,则和OPTR的栈顶元素θ1比较优先级,θ1和θ2进行比较。
当θ1 < θ2 ,θ2 进栈;表达式21+44-3*6的算法编程实现。
[动画演示]1.5分钟结合算法演示系统,讲解用栈求解表达式21+44-3*6的算法执行过程。
[小结]2分钟栈的定义,栈的“先进后出”的特性;栈的顺序存储的实现;栈的应用。
当θ1 = θ2 ,θ1 出栈;若θ1 > θ2 ,θ1 出栈,先进行操作数求值;然后运算结果再进栈。
3、算法编程实现OperandType EvaluateExpression ( ){ InitStack(OPTR);push(OPTR,`#`);InitStack(OPND);read(w);Whi le NOT ((w=’#’)AND (GetTop(OPTR)= `#`) )[IF w NOT IN op THEN[ push(OPND,w); read(w);ELSE CASEPrecede(GetTop(OPTR),w)OF`<`:[ push(OPTR,c); read(w);]`=`: [pop(OPTR,x);if x=FUNCTION thenPUSH(OPND,x(POP(OPNE)));read(w);]`>`: [b:= pop(OPND);a:= pop(OPND);theta:= pop(OPTR);push(OPND,Operate(a,theta,b));]ENDC; ]RETURN(POP(OPND))ENDF;4、算法执行过程# 21+44-3*6#1)“#”先压入到运算符栈,即push(OPTR,`#`);OPTR OPND2)push(OPND,`21`)2)‘#’ <‘+’,push(OPTR, `+` );3)push(OPND,`44`)。
数据结构第三章 栈和队列part2)

多个函数嵌套调用的规则是:
后调用先返回 !
此时的内存管理实行“栈式管理”
例如:
void main( ){ void a( ){
…
…
a( );
b( );
…
…
}//main
}// a
void b( ){
… 函数b的数据区 函数a的数据区 Main的数据区
}// b
递归函数执行的过程可视为同一 函数进行嵌套调用.
例七、实现递归
当在一个函数的运行期间调用另一个函 数时,在运行该被调用函数之前, 需先完成三项任务:
• 将所有的实在参数、返回地址等信息传 递给被调用函数保存;
• 为被调用函数的局部变量分配存储区; • 将控制转移到被调用函数的入口。
从被调用函数返回调用函数之前,应该 完成下列三项任务:
• 保存被调函数的计算结果; • 释放被调函数的数据区; • 依照被调函数保存的返回地址将控
从原表达式求得后缀式的规律为:
1) 设立操作数栈; 2) 设表达式的结束符为“#”,
预设运算符栈的栈底为“#”;
3) 若当前字符是操作数, 则直接发送给后缀式。
从原表达式求得后缀式的规律为:
4) 若当前运算符的优先数高于栈顶运算 符,则进栈;
5) 否则,退出栈顶运算符发送给后缀式;
6) “(” 对它之前后的运算符起隔离作 用,“)”可视为自相应左括弧开始的 表达式的结束符。
// 从终端接收下一个字符
}
将从栈底到栈顶的字符传送至调用过程的数据区;
ClearStack(S);
// 重置S为空栈
if (ch != EOF) ch = getchar();
}
栈的具体应用实验教学研究

v i c n es n ) / 于 输 入 的 任 意 一 个 非 负 十 进 制 od o vri ( / 对 o
整数 , 打印输 出与其等 值 的八 进制数
{
题 的算 法 , 最后 根据 算 法编 出程 序 , 进行 测 试 、 并 调整
直至得 到最终 解答 。
I i tc () / 语 句 1 构 造 名 为 S 空 栈 nt ak s ;/ S : 的 sa f“ d , ;/ 句 2 键 盘 读 入 十 进 制 数 N cn( ” N)/ 语 :
关 键 词 : 象数 据 类 型 算 法 栈 抽
通 常 在 用 计 算 机 解 决 一 个 具 体 问 题 时 , 致 需 要 大 经过 三个步骤 : 先从 具 体 问题 抽 象 出一 个适 当的数 首
学 模 型 , 后 在 此 数 学 模 型 的 基 础 上 设 计 一 个 解 决 问 然
例 如 :1 4 ) 一 ( 5 4 其 运 算 过 程 如 下 : ( 3 8 。 20 ),
N 1 48 3
18 6 2 1
p s ( , 8 ;/ 句 4 将 N 对 8取 模所 得 余 uh SN )/语 :
数压 人栈 S
N—N/ ; / 8 / 语句 5 将 N对 8取模所 得商赋 给 N, :
的 八进 制 数 。 由于 上 述 计 算 过 程 是 从 底 位 到 高 位 顺 序
p p se ;/ 句 7 对 当前 栈 顶 元 素 执 行 出 栈 操 o ( ,) / 语 :
作, 其值 由变 量 e 回 带
p it( d ,) / 语 句 8 打 印 输 出 变 量 e的值 r f“ ” e ;/ n :
科 教 论 坛
[计算机软件及应用]栈的应用和串图
![[计算机软件及应用]栈的应用和串图](https://img.taocdn.com/s3/m/62d61f359ec3d5bbfc0a74c2.png)
A. i-j-1 B. i-j
C. j-i+1 D. 不确定的
5. 若 已 知 一 个 栈 的 入 栈 序 列 是 1,2,3,…,n , 其 输 出 序 列 为 p1,p2,p3,…,pN,若pN是n,则pi是( D)。
A. i
B. n-i C. n-i+1 D. 不确定
6
2. 在作进栈运算时,应先判别栈是否( ① B),在作退栈运算时应 先判别栈是否( ② A )。当栈中元素为n个,作进栈运算时发生上
if(!In(c,OP)){Push(OPND,c); c=getchar();}//不是运算符则进入 栈
switch(Precede(GetTop(OPTR),c)){ case ‘<’: //栈顶元素的优先级低
Push(OPTR, c); c=getchar(); break;
case ‘=’: //脱括号并接受下一个字符;
例1数制转换
除基取余法
十进制N和其它进制数的转换是计算机实原理:
N=(n div d)*d+n mod d
( 其中:div为整除运算,mod为求余运算)
例如 (1348)10=(2504)8,其运算过程如下:
n n div 8 n mod 8
16. 栈在( D)中应用。
A. 递归调用 B. 子程序调用 C. 表达式求值 D. A,B,C
9
注:上述算法的匹配过程易于理解,且在某些应用场合,如文本 编辑等,效率也较高,但是在有些情况下,该算法的效率却很低。
其主串的指针i在不断的回溯,如i=3,变为i=2,i=7变为i=4… 其时间复杂度可达到O(n*m).
列得不到的出栈排列是( )。
A.XYZ
利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法利用栈来实现算术表达式求值的算法算术表达式是指按照一定规则组成的运算式,包含数字、运算符和括号。
在计算机中,求解算术表达式是一项基本的数学运算任务。
根据算术表达式的性质,我们可以考虑利用栈这一数据结构来实现求值算法。
一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(ReversePolish notation)。
逆波兰表达式是一种没有括号的算术表达式,其运算规则是先计算后面的数字和运算符,再计算前面的数字和运算符。
例如,对于算术表达式“3+4*5-6”,其对应的逆波兰表达式为“3 45 * +6 -”。
那么,我们可以利用栈来实现将中缀表达式转化为逆波兰表达式的过程,具体步骤如下:1. 创建两个栈——操作数栈和操作符栈。
2. 从左到右扫描中缀表达式的每一个数字和运算符,遇到数字则压入操作数栈中,遇到运算符则进行如下操作:(1)如果操作符栈为空或当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入操作符栈中。
(2)如果当前运算符的优先级小于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入操作数栈中,重复此过程直到遇到优先级较低的运算符或操作符栈为空为止,然后将当前运算符压入操作符栈中。
3. 扫描完中缀表达式后,若操作符栈不为空,则将其中所有运算符弹出并加入操作数栈中。
4. 最终,操作数栈中存放的就是逆波兰表达式,我们可以按照逆波兰表达式的计算规则来计算其结果。
二、算法优点利用栈来实现算术表达式求值的算法具有以下优点:1. 代码简洁易懂,易于实现和维护。
2. 由于将中缀表达式转化为逆波兰表达式后,可以减少运算符的优先级关系而消除括号,从而减少求值的复杂度,提高程序的执行效率。
三、代码实现下面是利用栈来实现算术表达式求值的算法的Python代码实现:```pythonclass Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def is_empty(self):return len(self.items) == 0def size(self):return len(self.items)def calculate(op_num1, op_num2, operator):if operator == "+":return op_num1 + op_num2elif operator == "-":return op_num1 - op_num2elif operator == "*":return op_num1 * op_num2elif operator == "/":return op_num1 / op_num2def infix_to_postfix(infix_expr):opstack = Stack()postfix_expr = []prec = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0} token_list = infix_expr.split()for token in token_list:if token.isdigit():postfix_expr.append(token)elif token == '(':opstack.push(token)elif token == ')':top_token = opstack.pop()while top_token != '(':postfix_expr.append(top_token)top_token = opstack.pop()else:while (not opstack.is_empty()) and(prec[opstack.peek()] >= prec[token]):postfix_expr.append(opstack.pop())opstack.push(token)while not opstack.is_empty():postfix_expr.append(opstack.pop())return " ".join(postfix_expr)def postfix_eval(postfix_expr):opstack = Stack()token_list = postfix_expr.split()for token in token_list:if token.isdigit():opstack.push(int(token))else:op_num2 = opstack.pop()op_num1 = opstack.pop()result = calculate(op_num1, op_num2, token) opstack.push(result)return opstack.pop()infix_expr = "3 + 4 * 5 - 6"postfix_expr = infix_to_postfix(infix_expr)print(postfix_expr)print(postfix_eval(postfix_expr))```四、总结算术表达式求值是一项常见的数学运算任务,利用栈这一数据结构来实现求值算法是一种简单有效的方法,它将中缀表达式转化为逆波兰表达式后,可以消除括号并减少运算符的优先级关系,从而提高程序的执行效率。
实验三 栈的基本操作

实验三栈的基本操作实验三栈的基本运算学号:0700710319 姓名:梁浩然实验日期:2021年5月6日一、实验目的:(1)掌握栈的各种存储结构及基本运算的实现。
(2)掌握堆栈后进先出的运算原则在解决实际问题中的应用。
(3)复习c语言中相关语句及函数的用法。
(4)进一步熟悉c语言的相关知识,能够把某些c语言知识应用得自如一点。
(5)一定要自己先完成实验的课后习题,认真的思考,能够达到独立思考。
二、实验要求:(1)熟练掌握栈的存储结构及其基本操作。
(2)理解所给出的算法,掌握栈在实际中的应用。
(3)将上机程序调试通过,并能独立完成一至两个拓展题目。
(4)一定要读书老师所给出来的程序。
三、实验内容:认真阅读数据结构的课本,熟悉所学的知识,认真复习c语言的相关的知识,然后对括号配对检查。
试设计一个程序对任意输入的语句或数学表达式,判断其括号是否匹配。
若匹配,则返回1,否则返回0。
调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果,加深对算法的理解。
四、实验步骤:首先建立一个栈结构,且初始化栈为空。
然后由键盘上随即输入一个带括号的语句或带括号的数学表达式,同时将它们保存在一个字符型数组exps[]中。
扫描表达式exps,当遇到“(”、“[”、“{”时,将其入栈。
遇到“)”、“]”、“}”时,判断栈顶是否有相匹配的括号。
若没有,则退出扫描过程,返回0,否则直到exps扫描完毕为止。
若top为0,则返回1。
(程序略)五、实验预期的效果:(1)认真的研究实验所给的程序;(2)能读懂实验所给的程序,并且自己可以在计算机上调试成功;(3)根据实验所学的知识能做好老师布置给我们的作业,编写程序并且调试出来运行成功。
(4)在试验后自己要认真的总结该次实验所收获的东西。
六、实验方法实验所给程序修改如下:#include \#define MAXSIZE 100 #define TRUE 1 #define FALSE 0 #define NULLtypedef int datatype;typedef struct /*顺序栈的结构体类型定义*/ {datatype stack[MAXSIZE];int top; }seqstack;void setnull(seqstack *s) //置空栈-由于c语言的数组下标是从0开始的,所以置 {s->top=-1;} //空栈操作时将栈顶指针放在下标为0之前,即-1处。
利用栈实现数制转换(10进制转换8进制)

利用栈实现数制转换(10进制转换8进制)//利用栈实现数制转换(10进制转换8进制)#include#include#define ERROR 0#define OK 1#define STACK_INIT_SIZE 100 //存储空间初始分配量#define STACKINCREMENT 10 //存储空间分配增量typedef int SElemType;typedef struct stack{SElemType *top;SElemType *bottom;int stacksize;}SqStack;int InitStack(SqStack *S){//构造一个空栈S->bottom=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SEl emType));if(!S->bottom) return ERROR; //存储分配失败S->top=S->bottom;S->stacksize=STACK_INIT_SIZE;return OK;} //InitStackint Push(SqStack *S,SElemType e){//插入元素e为新的栈顶元素if(S->top-S->bottom>=S->stacksize-1){S->bottom=(SElemType*)realloc(S->bottom,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S->bottom)return ERROR; //S->top=S->bottom+S->stacksize;}*S->top++=e;return OK;} //Pushint Pop(SqStack *S,SElemType *e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR;if(S->top==S->bottom)return ERROR;*e=*--S->top;return OK;} //Popint StackEmpty(SqStack S){if(S.top==S.bottom)return 1;else return 0;}void main(){SqStack myStack;int N,e;InitStack(&myStack);printf("请输入N:");scanf("%d",&N);while(N){Push(&myStack,N%8);N=N/8;}while(!StackEmpty(myStack)) {Pop(&myStack,&e);printf("%d",e);}printf("\n");}上一页下一页。
数据结构应用(栈——基础知识)

链栈的基本操作
⑷ 出栈
int Pop(LinkStack top,DataType *x) { /* 将栈head的栈顶元素弹出,放到x所指的存储空间中 */ if(top==NULL) /*栈为空*/ return ERROR; *x=top->data; LinkStack p = top; top =top->next; delete p; /* 释放存储空间 */ return TRUE; }
s .top =0 (b)进栈
s .top =4 (c)栈满
s .top =2 (d)出栈
顺序栈的基本操作
⑴ 置空栈:首先建立栈空间,然后初始化栈 顶指针。 SeqStack *Init () { SeqStack *s; s=new SeqStack;
s->top= -1;
return s;
}
顺序栈的基本操作
an
栈顶
…...
a3 a2 a1 ^ 栈底
栈的链式存储定义
typedef struct Node { DataType data; Node *next; }StackNode,* LinkStack;
链栈的基本操作
⑴ 置空栈 void Init(LinkStack top) { top = NULL; }
顺序栈的基本操作
⑸ 取栈顶元素 DataType GetTop(SeqStack *s) { if ( IsEmpty ( s ) ) return ERROR; //栈空 return s->data[s->top]; }
链栈的操作实现
链栈的示意
•若是栈中元素的数目变化 top 范围较大或不清楚栈元素的 数目,就应该考虑使用链式 存储结构。人们将用链式存 储结构表示的栈称作“链 栈”。 • 由于栈的插入删除操作只 能在一端进行,而对于单链 表来说,在首端插入删除结 点要比尾端相对地容易一些。
数制转换的作用

数制转换的作用数制转换是指将一个数字表示从一种数制转换成另一种数制的过程。
数制转换在计算机科学、数学、电子工程等领域中被广泛应用,其作用十分重要。
本文将从不同的角度探讨数制转换的作用。
一、数制转换在计算机科学中的作用在计算机科学领域中,数制转换是十分常见的操作。
计算机以二进制形式来处理和存储数据,而人们通常使用十进制来表达数字。
因此,需要进行二进制到十进制的数制转换。
数制转换在计算机科学中的作用主要体现在以下几个方面:1. 数据存储和传输:计算机内部的数据存储和传输都是以二进制形式进行的。
然而,当人们需要将数据从计算机中读取或者将数据传输到计算机中时,通常需要将数据转换成十进制形式,以便人们理解和使用。
2. 程序设计:在程序设计中,经常需要进行位操作或者使用二进制运算符。
因此,掌握二进制数制转换对于理解和编写程序是至关重要的。
3. 地址转换:计算机内存中的地址通常是以二进制形式表示的。
当需要将二进制地址转换成十进制地址时,数制转换就发挥了重要作用。
二、数制转换在数学中的作用在数学领域中,数制转换也有其重要的作用。
数制转换主要涉及到不同进制的数之间的转换,如二进制、八进制、十进制和十六进制等。
数制转换在数学中的作用主要体现在以下几个方面:1. 进一制和进位制:数制转换是进一制和进位制的具体应用。
在进位制中,当某一位的数超过进制数时,需要向高位进位。
而在进一制中,当某一位的数达到最大值时,需要向高位进一。
因此,掌握数制转换可以帮助我们理解和应用进位制和进一制。
2. 数字表达的灵活性:不同的数制有不同的特点和应用场景。
例如,八进制和十六进制在计算机科学中被广泛使用,因为它们可以更紧凑地表示二进制数据。
而十进制在日常生活中更为常见,因为它更符合人们的思维习惯。
因此,数制转换可以帮助我们在不同场景下选择合适的数制来表示数字。
3. 数字逻辑和编码:数制转换在数字逻辑和编码中也有重要应用。
例如,将二进制数转换成格雷码可以简化数字电路的设计。
第3章演示

3.1.2 栈的表示和实现
2. 链栈 链栈是用链式存储结构实现的栈,即利用不连续 的存储单元依次存放自栈底到栈顶的数据元素。
说明: (1)头指针就是栈顶指针top; (2) 链表结点指针指向前一个入栈的元素,体现入栈 的先后顺序; (3)既为链栈,则插入/删除操作只能在链表头结点处 进行。
3.1.3 栈的应用举例 一、 数制转换 对于输入的任意一个非负十进制整数,打印输 出与其等值的八进制数。 例如:(1348)10=(?)8 从其计算过程进行分析,可以发现将十进制数 N转换为八进制数,在重复执行如下两步: X = N mod 8 (其中mod为求余运算) N = N div 8 (其中div为整除运算) 直到N为0
1. 顺序栈 (2) 算法的实现
③判栈满。
int Stackoverflow(SqStack S)
/*判栈S为满栈时返回值为真, 反之为假*/
{return(S.top==MAXSIZE-1?TRUE:FALSE);}
1. 顺序栈 (2) 算法的实现 ④ 进栈。 <i> 判栈满; <ii>将栈顶指针top上移,存入元素。 ⑤ 出栈。 <i> 判栈空; <ii> 取出栈顶元素,将栈顶指针top下移; <iii>返回栈顶元素。
3.1.3 栈的应用举例 二、 算术表达式求值 1、算术四则运算的规则 2、表达式的构成规则 3、算法分析 (1)规定优先级表 (2)使用两个工作栈:optr 算符栈和opnd操作数栈
4、程序实现
3.1.3 栈的应用举例 二、 算术表达式求值 1、算术四则运算的规则: (1)括号优先级最高; (2)先乘除,后加减; (3)同优先级的遵循从左向右的结合性。
利用栈的基本操作实现将任意一个十进制整数转化为R进制整数

利用栈的基本操作实现将任意一个十进制整数转化为R进制整数。
算法为:1、定义栈的顺序存取结构2、分别定义栈的基本操作(初始化栈、判栈为空、出栈、入栈等)3、定义一个函数用来实现上面问题:(1)十进制整数X和R作为形参(2)初始化栈(3)只要X不为0重复做下列动作将X % R入栈, X=X/R(4)只要栈不为空重复做下列动作栈顶出栈 , 输出栈顶元素#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define stack_init_size 100#define stackincrement 10typedef struct sqstack{int *base;int *top;int stacksize;} sqstack;int StackInit(sqstack *s){s->base=(int *)malloc(stack_init_size *sizeof(int));if(!s->base)return 0;s->top=s->base;s->stacksize=stack_init_size;return 1;}int Push(sqstack *s,int e){if(s->top-s->base>=s->stacksize){s->base=(int *)realloc(s->base,(s->stacksize+stackincrement)*sizeof(int));if(!s->base)return 0;s->top=s->base+s->stacksize;s->stacksize+=stackincrement;}*(s->top++)=e;return e;}int Pop(sqstack *s,int e){if(s->top==s->base)return 0;e=*--s->top;return e;}int stackempty(sqstack *s){if(s->top==s->base){return 1;}else{return 0;}}int conversion(sqstack *s){int n,e=0,flag=0;printf("输入要转化的十进制数:\n");scanf("%d",&n);printf("要转化为多少进制:2 进制、8 进制、16 进制填数字!\n");scanf("%d",&flag);printf("将十进制数%d 转化为%d 进制是:\n",n,flag);while(n){Push(s,n%flag);n=n/flag;}while(!stackempty(s)){e=Pop(s,e);switch(e){case 10: printf("A");break;case 11: printf("B");break;case 12: printf("C");break;case 13: printf("D");break;case 14: printf("E");break;case 15: printf("F");break;default: printf("%d",e);}}printf("\n");return 0;}int main(){sqstack s;StackInit(&s);conversion(&s);return 0;}。
栈和队列是两种特殊的线性表,是操作受限的线性表,简称限

27
-----入栈(3) ----top
…... 栈底 ^
x
Status push(LinkStack &top,SElemType x){ //入栈 StackNode *p=new StackNode; if(!p) exit(OVERFLOW); p->data=x; p->next=top; top=p; return OK; }
25
2.链栈的操作
-----初始化链栈(1) ----void InitStack (LinkStack &top){
// 构造一个空的链栈 top
top = NULL;
}
26
-----判空链栈 (2)-----
int StackEmpty(LinkStack top){
return(top==NULL);
5
……...
栈s=(a1,a2,……,an)
栈的概念
出栈 Pop 进栈 Push
第一个进栈的元素在栈底,
最后一个进栈的元素在栈顶, 第一个出栈的元素为栈顶元素,
最后一个出栈的元素为栈底元素。
不含元素的栈称为空栈。
top
栈顶
an
. . .
空栈 top base
6
a2
栈底
base
a1
主要操作:入栈与出栈
top
top top base
A
A进栈
base
E D C B A
base
E D C B A
E D C 出栈
B C D E 进栈
栈的特点 后进先出LIFO
7
思考:假设有A,B,C三个元素进S栈的顺序是 A,B,C,写出所有可能的出栈序列。
栈的应用举例

大整数相加
• 相加从低位开始,输出从高位开始 • 用两个栈保存操作数(大整数) • 结果保存到结果栈
数制转换 数制转换的原理为: N = (N div d)×d + N mod d × 例如: 例如:(1348)10 转换成 (2504)8 的运算 过程如下: N N div 8 N mod 8 计 输 1348 168 4 算 出 168 21 0 顺 顺 21 2 5 序 序 2 0 2
检验含两种括弧的表达式中括弧匹配的 正确性。 如表达式中 ([]())或[([ ][ ])] ([]())或 等为正确的匹配, [(])或([()] [(])或([() 或 [ ( ) ] ) 均为不正确的匹配。 检验括弧匹配的方法可用“按期待的 急迫程度进行处理”描述之 。
例如 考虑下列括号序列:
[ ( [ ] [ ( ) ])]
可见,括弧匹配也遵循“后进先出”的规 律。 如何表示下列“不匹配 的情 不匹配” 不匹配 况? • 到来的右括弧非是所“期待”的; • 来了一个“不速之客”; • 直到结束,也没有等到“期待”的匹 配;
算法的设计思想: 算法的设计思想:
1)凡出现左括弧 左括弧,则进栈 进栈; 左括弧 进栈 2)凡出现右括弧 右括弧,首先检查栈是否空? 右括弧 若栈空 栈空,则表明该“右括弧”多余 “右括弧” 栈空 否则和栈顶元素 和栈顶元素比较, 和栈顶元素 若相匹配 相匹配,则“左括弧出栈” 相匹配 “左括弧出栈” 否则表明不匹配 不匹配 3)表达式 表达式检验结束时 结束时, 表达式 结束时 若栈空 栈空,则表明表达式中匹配正确 栈空 匹配正确 否则表明“左括弧”有余。 “左括弧”有余。
栈的应用举例

数据结构
栈的应用举例
1、数制转换(十转N)
设计思路:用栈暂存低位值
2、括号匹配问题
设计思路:用栈暂存左括号
3、子程序的调用
设计思路:用栈暂存指令地址
4、逆置一个单链表
设计思路:用栈暂存每一结点
例3.2 将十进制整数转换成二至九之间的任一进 制数输出
将一个十进制数4327转换成八进制数(10347)8:
void conversion(int N, int r)
解题思路如下:
{ int x=N,y=r; SeqStack *s;
s=InitStack(); while(Ns中;
{ Push(s, N %r ); N=N/r ;
2、用N/r代替N;
数据结构
解题思路如下:
1、建立一个带头结点的单链表 head; 2、输出该单链表; ; 3、建立一个空栈s(顺序栈); 4、依次将单链表的数据入栈; 5、依次将单链表的数据出栈, 并逐个将出栈的数据存入单链 表的数据域(自前向后);
6、再输出单链表。
linklist*backlinklist(linklist *head) {linklist *p;
3、若N>0,则重复 (1)、(2);若N=0, 则将栈s的内容依次出 栈。
}
printf(“\n 十 进 制 数 %d 所 对 应 的 %d 进 制 数是:”,x,y);
栈和队列是两种特殊的线性表,是操作受限的线性表,简称限

35
(3)共享出栈算法 ElemType pop1( ){ if (top1==0){ cout<<“underflow\n”;return(NULL);} top1--; return(stack[top1]);} ElemType pop2( ){ if(top2==MAX-1){ cout<<“underflow\n”);return(NULL);} top2++; return(stack[top2]);}
top
top top base
A
A进栈
base
E D C B A
base
E D C B A
E D C 出栈
B C D E 进栈
栈的特点 后进先出LIFO
7
思考:假设有A,B,C三个元素进S栈的顺序是 A,B,C,写出所有可能的出栈序列。
A ABC ACB BAC BCA CAB CBA
8
B B C
if (StackFull (S)) return ERROR; *S.top++=x;
return OK;
}
20
-----出栈(5)----Status Pop (SqStack &S, SElemType &e) {
//若栈空返回0, 否则栈顶元素退出到e,并返回1
if ( StackEmpty(S) ) return ERROR;
32
-----创建链栈 (8)----void create_stack(LinkStack &top){ for(char ch='a';ch<='g';ch++)
用栈对数字倒叙的作用

用栈对数字倒叙的作用栈是一种数据结构,它的特点是先进后出,后进先出。
因此,栈可以用来实现数字的倒序。
在计算机中,数字都是以二进制形式存储的,而二进制数的每一位都代表2的n次方,n为该位所在的位数,从右往左数。
例如,二进制数1010中,右边第一位代表2的0次方,即1,右边第二位代表2的1次方,即2,右边第三位代表2的2次方,即4,右边第四位代表2的3次方,即8。
因此,如果要将一个十进制数倒序,就需要先将它转为二进制,然后将二进制的每一位依次压入栈中,最后依次弹出栈中的元素,即可得到倒序的结果。
下面以数字1234为例,介绍用栈对数字倒序的作用。
1. 将数字1234转为二进制数首先将数字1234转为二进制数。
可以使用短除法的方法,即每次将数字除以2,将余数保存下来,并将商作为新的被除数,直到商为0为止。
例如:1234 ÷ 2 = 617 0617 ÷ 2 = 308 (1)308 ÷ 2 = 154 0154 ÷ 2 = 77 077 ÷ 2 = 38 (1)38 ÷ 2 = 19 019 ÷ 2 = 9 (1)9 ÷ 2 = 4 (1)4 ÷ 2 = 2 02 ÷ 2 = 1 01 ÷ 2 = 0 (1)将上述的余数倒序排列,得到二进制数10011010010。
2. 将二进制数的每一位压入栈中下一步,将二进制数的每一位依次压入栈中。
从右往左数,依次将0、1、0、0、1、1、0、1、1、0压入栈中。
3. 依次弹出栈中的元素,得到倒序的结果最后,依次从栈中弹出元素,得到倒序的结果为0110100110,即将数字1234倒序后得到的二进制数。
总之,使用栈可以方便地实现数字倒序的功能。
它可以将待处理的数字按位分解,并将分解出来的每一位保存下来,最后按照倒序的顺序输出,从而得到倒序的结果。
这在计算机网络和数据存储领域有广泛应用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数制转换:
十进制数N和其它d进制数的转换是计算机实现计算的基本问题,其解决方法很多,其中一种简单方法基于以下原理.
N=(N div d)*d+N mod d (其中:div为整除运算,mod 为求余运算.)
例如:10进制数1348转换为8进制为:2504.其运算过程如下:
N N div d N mod d
1348 168 4
168 21 0
21 2 5
2 0 2
假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数,打印输出与其相等的八进制数,由于上述计算过程是从低位到高位顺序产生八进制数的各个位数,而打印输出,一般来说应从高位到低位进行,恰好和计算过程相反.因此,若将计算过程中得到的八进制数的各位顺序进栈,则按出栈序列打印输出的即为与输入对应的八进制数.
算法描述如下:
void conversion()
{
InitStack(s);
scanf(" %d",N);
while(N)
{
push(s,n%8)
N=N/8;
}
while(!StackEmpty(s))
{
Pop(S,e);
printf("%d",e);
}
}
这个是利用栈的先进后出特性的最简单的例子.在这个例子中,栈操作的序列是直线式的,即先一味地进栈,然后一味的出栈.也许有人会提出疑问:用数组直接实现不也很简单吗?仔细分析上述算法不难看出,栈的引入简化了程序设计的问题,划分了不同的关注层次,使思考的范围缩小了.而用数组不仅掩盖了问题的本质,还要分散精力去考虑数组下标增减等细节.
完整代码实现:
#include<iostream>
#include<stack>
using namespace std;
void change(int n,int d)
stack<int>s;
int temp;
int i=0;
if(n<d)
{
cout<<n<<endl;
}
else
{
while(n)
{
temp=n%d;
s.push(temp);
n=n/d;
}
while(!s.empty())
{
temp=s.top();
cout<<temp;
s.pop();
}
cout<<endl;
}
}
void main()
{
int x,y;
cout<<"请输入你要转换的数字&qu(参考:)ot;<<endl;
cin>>x;
cout<<"请输入你要转换的进制"<<endl;
cin>>y;
change(x,y);
}
递归实现十进制转换为八进制:/*
Name: conversion.cpp
Copyright:
Author: HeHe.wang
Date: 16-06-12 13:03
Description:
*/
#include <iostream>
using namespace std;
void conversion(int N,int d)
{
int temp=N%d;
N=N/d;
if(N==0)
cout<<temp;
else
{
conversion(N,d);
cout<<N%d;
}
}
int main()
{
conversion(7,2);
system("pause");
}文章出自:我爱程序员
/archives/1039.html 版权所有.本站文章除注明出处外,皆为作者原创文章,可自由引用,但请注明来源.。