递归
分治思想: 折半查找算法的递归实现
汉诺塔问题
八皇后
逆波兰(Reverse Polish Notation, RPN)表示
中缀表达式转后缀表达式
二进制转为十进制
递归
1.斐波那契数列的实现
递归的思想:
/***************************************
* 数据结构和算法--小甲鱼
* 递归print
****************************************/
/*
#include <stdio.h>
//递归打印print
void print ()
{
char inputChar;
scanf("%c" ,&inputChar);
if(inputChar != '#') print();
if(inputChar != '#') printf("%c",inputChar);
}
int main()
{
while(1){
printf("请输入一串字符串,以\"#\" 结束:\n ");
print();
}
return 0;
}
分治思想: 折半查找算法的递归实现
/***************************************
* 数据结构和算法--小甲鱼
* 分治思想 :二分查找法
****************************************/
#include <stdio.h>
int bin_search(int key[] , int low , int high , int k)
{
int mid;
if( low > high )
{
return -1;
}
else
{
mid = (low + high) / 2;
if(key[mid] == k)
{
return mid;
}
if( k >key[mid])
{
return bin_search(key, mid + 1 , high , k);
}
else {
return bin_search(key , low ,mid - 1, k);
}
}
}
int main()
{
int str[11] = {1,2,3,3,4,5,5,5,5,6,7};
int n , addr;
printf("请输入待查找的关键字: ");
scanf("%d", &n);
addr = bin_search(str, 0, 10, n);
if( -1 != addr )
{
printf("查找成功,可喜可贺,可口可乐! 关键字 %d 所在的位置是: %d\n", n, addr);
}
else
{
printf("查找失败!\n");
}
return 0;
}
汉诺塔问题:
/***************************************
* 数据结构和算法--小甲鱼
* 分治思想 :汉诺塔
****************************************/
/*
#include <stdio.h>
// 将 n 个盘子从 x 借助 y 移动到 z
void move(int n, char x, char y, char z)
{
if( 1 == n )
{
printf("%c-->%c\n", x, z);
}
else
{
move(n-1, x, z, y); // 将 n-1 个盘子从 x 借助 z 移到 y 上
printf("%c-->%c\n", x, z); // 将 第 n 个盘子从 x 移到 z 上
move(n-1, y, x, z); // 将 n-1 个盘子从 y 借助 x 移到 z 上
}
}
int main()
{
int n;
printf("请输入汉诺塔的层数: ");
scanf("%d", &n);
printf("移动的步骤如下: \n");
move(n, 'X', 'Y', 'Z');
return 0;
}
八皇后: //趣学算法 有讲解 回溯法
#include <stdio.h>
int count = 0;
int notDanger( int row, int j, int (*chess)[8] )
{
int i, k, flag1=0, flag2=0, flag3=0, flag4=0, flag5=0;
// 判断列方向
for( i=0; i < 8; i++ )
{
if( *(*(chess+i)+j) != 0 )
{
flag1 = 1;
break;
}
}
// 判断左上方
for( i=row, k=j; i>=0 && k>=0; i--, k-- )
{
if( *(*(chess+i)+k) != 0 )
{
flag2 = 1;
break;
}
}
// 判断右下方
for( i=row, k=j; i<8 && k<8; i++, k++ )
{
if( *(*(chess+i)+k) != 0 )
{
flag3 = 1;
break;
}
}
// 判断右上方
for( i=row, k=j; i>=0 && k<8; i--, k++ )
{
if( *(*(chess+i)+k) != 0 )
{
flag4 = 1;
break;
}
}
// 判断左下方
for( i=row, k=j; i<8 && k>=0; i++, k-- )
{
if( *(*(chess+i)+k) != 0 )
{
flag5 = 1;
break;
}
}
if( flag1 || flag2 || flag3 || flag4 || flag5 )
{
return 0;
}
else
{
return 1;
}
}
// 参数row: 表示起始行
// 参数n: 表示列数
// 参数(*chess)[8]: 表示指向棋盘每一行的指针
void EightQueen( int row, int n, int (*chess)[8] )
{
int chess2[8][8], i, j;
for( i=0; i < 8; i++ )
{
for( j=0; j < 8; j++ )
{
chess2[i][j] = chess[i][j];
}
}
if( 8 == row )
{
printf("第 %d 种\n", count+1);
for( i=0; i < 8; i++ )
{
for( j=0; j < 8; j++ )
{
printf("%d ", *(*(chess2+i)+j));
}
printf("\n");
}
printf("\n");
count++;
}
else
{
for( j=0; j < n; j++ )
{
if( notDanger( row, j, chess ) ) // 判断是否危险
{
for( i=0; i < 8; i++ )
{
*(*(chess2+row)+i) = 0;
}
*(*(chess2+row)+j) = 1;
EightQueen( row+1, n, chess2 );
}
}
}
}
int main()
{
int chess[8][8], i, j;
for( i=0; i < 8; i++ )
{
for( j=0; j < 8; j++ )
{
chess[i][j] = 0;
}
}
EightQueen( 0, 8, chess );
printf("总共有 %d 种解决方法!\n\n", count);
return 0;
}
后缀表达法 ,逆波兰(Reverse Polish Notation, RPN)表示。
“9+(3-1)×3+10÷2”,如果要后缀表示法应该是什么样子:“9 3 1-3*+10 2/+”这样的表达式称为后缀表达式,叫后缀的原因在于所有的符号都是在要运算数字的后面出现。
后缀表达式:9 3 1-3*+10 2/+
规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
//自己写的
#include "DaHuaShuJuJieGou.h"
//后缀表达式的运算
int main()
{
//从左到右遍历 ,如果是数字就进栈
//遇到符号,就将两个栈顶的数字出栈
//然后将结果再入栈
char c , res ,e;
SqStack s;
InitStack(&s);
printf("请输入后缀的表达式:\n");
scanf("%c",&c);
while(c != '#')
{
if(c>='0' && c<='9')
{
printf("%d\n",c);
Push(&s,c);
}
else if(c == '*'|| c=='/'||c=='+'||c=='-')
{
Pop(&s , &e);
res += e;
Pop(&s , &e);
res += e;
Push(&s , res);
}
scanf("%c",&c);
}
printf("%c\n", res);
return 0;
}
中缀表达式转后缀表达式
即“9+(3-1)×3+10÷2”叫做中缀表达式。因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化。
中缀表达式“9+(3-1)×3+10÷2”转化为后缀表达式“9 3 1-3*+10 2/+”。
规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级不高于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。
1+(2-3)*4+10/5 :步骤:
1.直接输出数字 1
2. + 入栈
3.(入栈
4. 直接输出 数字 2
5 . - 入栈
6. 直接输出数字3
7. 紧跟着是“)”,此时,我们需要去匹配栈里的“(”,然后再匹配前将栈顶数据依次出栈
8.那么就输出 -
9. 就 剩 下
10. *入栈
11. 直接输出数字 4
12.符号“+”,此时栈顶元素是符号“*”,按照先乘除后加减原理,此时栈顶的乘号优先级比即将入栈的加好要大,所以出栈。
即 输出 *
13. 接着就是 + 号, 但是和里面的 + 号 相同,那么按照先来先出的原则,把里面的 + 号也输出,把新的 + 号,放入。
14.接着输出 10
15.接着放 / 号
16.输出 数字 5
17.将栈中的元素 依次出栈
int main()
{
sqStack s;
char c, e;
InitStack( &s );
printf("请输入中缀表达式,以#作为结束标志:");
scanf("%c", &c);
while( c != '#' )
{
while( c>='0' && c<='9' )
{
printf("%c", c);
scanf("%c", &c);
if( c<'0' || c>'9' )
{
printf(" ");
}
}
if( ')' == c )
{
Pop(&s, &e);
while( '(' != e )
{
printf("%c ", e);
Pop(&s, &e);
}
}
else if( '+'==c || '-'==c )
{
if( !StackLen(s) )
{
Push(&s, c);
}
else
{
do
{
Pop(&s, &e);
if( '(' == e )
{
Push(&s, e);
}
else
{
printf("%c ", e);
}
}while( StackLen(s) && '('!=e );
Push(&s, c);
}
}
else if( '*'==c || '/'==c || '('==c )
{
Push(&s, c);
}
else if( '#'== c )
{
break;
}
else
{
printf("\n出错:输入格式错误!\n");
return -1;
}
scanf("%c", &c);
}
while( StackLen(s) )
{
Pop(&s, &e);
printf("%c ", e);
}
return 0;
}
二进制转为十进制
int main()
{
ElemType c;
sqStack s;
int len, i, sum = 0;
InitStack(&s);
printf("请输入二进制数,输入#符号表示结束!\n");
scanf("%c", &c);
while( c != '#' )
{
Push(&s, c);
scanf("%c", &c);
}
getchar(); // 把'\n'从缓冲区去掉
len = StackLen(s);
printf("栈的当前容量是: %d\n", len);
for( i=0; i < len; i++ )
{
Pop(&s, &c);
sum = sum + (c-48) * pow(2, i);
}
printf("转化为十进制数是: %d\n", sum);
return 0;
}
二进制转为十六进制
/*****************************/
/** 二进制/十六进制转换器 **/
/** By www.fishc.com 小甲鱼 **/
/*****************************/
int main()
{
ElemType c;
sqStack s1;
sqStack s2;
int len, i, j, sum = 0;
InitStack(&s1); // 初始化栈s1,用来存放二进制输入
printf("请输入二进制数,输入‘#’号表示结束!\n\n");
scanf("%c", &c);
while( c != '#' )
{
if( c=='0' || c=='1' ) // 检查输入是否二进制
Push(&s1, c);
scanf("%c", &c);
}
getchar(); // 把'\n'从缓冲区去掉
len = StackLen(s1);
InitStack(&s2); // 初始化栈s2,用来存放转换的八进制
for( i=0; i < len; i+=4 )
{
for( j=0; j < 4; j++ )
{
Pop( &s1, &c ); // 取出栈顶元素
sum = sum + (c-48) * pow(2, j);
if( s1.base == s1.top )
{
break;
}
}
switch( sum )
{
case 10: sum = 'A'; break;
case 11: sum = 'B'; break;
case 12: sum = 'C'; break;
case 13: sum = 'D'; break;
case 14: sum = 'E'; break;
case 15: sum = 'F'; break;
default: sum += 48;
}
Push( &s2, sum );
sum = 0;
}
printf("\n转化为十六进制数是: ");
while( s2.base != s2.top )
{
Pop( &s2, &c );
printf("%c", c);
}
printf("(H)\n");
return 0;
}
二进制转为八进制
/*****************************/
/** 二进制/八进制转换器 **/
/** By www.fishc.com 小甲鱼 **/
/*****************************/
int main()
{
ElemType c;
sqStack s1;
sqStack s2;
int len, i, j, sum = 0;
InitStack(&s1); // 初始化栈s1,用来存放二进制输入
printf("请输入二进制数,输入‘#’号表示结束!\n\n");
scanf("%c", &c);
while( c != '#' )
{
if( c=='0' || c=='1' ) // 检查输入是否二进制
Push(&s1, c);
scanf("%c", &c);
}
getchar(); // 把'\n'从缓冲区去掉
len = StackLen(s1);
InitStack(&s2); // 初始化栈s2,用来存放转换的八进制
for( i=0; i < len; i+=3 )
{
for( j=0; j < 3; j++ )
{
Pop( &s1, &c ); // 取出栈顶元素
sum = sum + (c-48) * pow(2, j);
if( s1.base == s1.top )
{
break;
}
}
Push( &s2, sum+48 );
sum = 0;
}
printf("\n转化为八进制数是: ");
while( s2.base != s2.top )
{
Pop( &s2, &c );
printf("%c", c);
}
printf("(O)\n");
return 0;
}
逆波兰计算器//没看
实现对逆波兰输入的表达式进行计算。 支持带小数点的数据。
正常的表达式 ---> 逆波兰表达式
a+b ---> a b +
a+(b-c) ---> a b c - +
a+(b-c)*d ---> a b c - d * +
a+d*(b-c)---> a d b c - * +
int main()
{
sqStack s;
char c;
double d, e;
char str[MAXBUFFER];
int i = 0;
InitStack( &s );
printf("请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志: \n");
scanf("%c", &c);
while( c != '#' )
{
while( isdigit(c) || c=='.' ) // 用于过滤数字
{
str[i++] = c;
str[i] = '\0';
if( i >= 10 )
{
printf("出错:输入的单个数据过大!\n");
return -1;
}
scanf("%c", &c);
if( c == ' ' )
{
d = atof(str);
Push(&s, d);
i = 0;
break;
}
}
switch( c )
{
case '+':
Pop(&s, &e);
Pop(&s, &d);
Push(&s, d+e);
break;
case '-':
Pop(&s, &e);
Pop(&s, &d);
Push(&s, d-e);
break;
case '*':
Pop(&s, &e);
Pop(&s, &d);
Push(&s, d*e);
break;
case '/':
Pop(&s, &e);
Pop(&s, &d);
if( e != 0 )
{
Push(&s, d/e);
}
else
{
printf("\n出错:除数为零!\n");
return -1;
}
break;
}
scanf("%c", &c);
}
Pop(&s, &d);
printf("\n最终的计算结果为:%f\n", d);
return 0;
}
// 5 - (6 + 7) * 8 + 9 / 4
// 5 - 13 * 8 + 9 / 4
// 5 - 104 + 2.25
// -99 + 2.25
// 5 6 7 + 8 * - 9 4 / +