目录
前言
此学习笔记来源 嵌入式技术公开课 数据结构教程
此学习笔记持续更新......欢迎交流。
00数据结构开篇
数据结构+算法=程序
算法:计算机处理问题的步骤
数据结构:作为处理对象的数据的摆列方式
数据才是程序的中心
数据结构就是组织数据最有效的摆列方式
高级程序员:数据结构+算法+数学思想+流程控制+逻辑思维
数据结构:
1,基础数据结构:栈,队列,树,链表
2,图
3,排序
4,查找/搜索
5,高级数据结构
算法:
贪心算法,分制发,动态规划,回朔法
01栈的实现原理
数组+循环 == 栈 队列
01.1 什么是栈?
...... 类似于弹夹 ...进电梯 ...箱里的书
后入先出 先入后出
栈里的内容可以是任意数据类型(数组存放的内容)
01.2 对于栈的操作
入栈 出栈 判断栈是否为空
指针一直指向栈顶空白
代码实例
#include <stdio.h>
char stack[512];
int top = 0;
void push(char c);
char pop(void);
int is_empty(void);
int main(void)
{
push('a');
push('b');
push('c');
while(!is_empty())
{
putchar(pop());
}
printf("\n");
return 0;
}
void push(char c)
{
stack[top++] = c;
}
char pop(void)
{
return stack[--top];
}
int is_empty(void)
{
/*
if(top == 0)
return 1;
else
return 0;
*/
return top == 0;
}
02栈的实际应用
02.1 逆波兰表示法
想一想计算机实现下列运算?
5*(((8+9)*(4*6))+7)
计算的开始 有不确定性
那么如何才能把这种不确定性转化位决定性!
如果有(1+2)*(3-4)
逆波兰表示 12+34-*
从左到右 遇到数字入栈 遇到操作符 连续两次出栈并计算 结果入栈
最后得出什么? 没错就是遵守四则运算后的结果
在算算89+46**7+5* 看看结果是否跟你想的一样!
下面给出具体实现的代码
#include <stdio.h>
#include <string.h>
int stack[512];
int top = 0;
void push(int c);
int pop(void);
int is_empty(void);
int main(void)
{
char a[100];
int n;
int i;
int n1, n2;
printf("Please enter a reverse polish expression:\n");
gets(a);
n = strlen(a);
for(i = 0; i < n; i++)
{
if((a[i] >= '0') && (a[i] <= '9'))
push(a[i] - '0');
else
{
n2 = pop();
n1 = pop();
switch(a[i])
{
case '+':
push(n1 + n2);
break;
case '-':
push(n1 - n2);
break;
case '*':
push(n1 * n2);
break;
}
}
}
printf("result = %d\n", pop());
return 0;
}
void push(int c)
{
stack[top++] = c;
}
int pop(void)
{
return stack[--top];
}
int is_empty(void)
{
/*
if(top == 0)
return 1;
else
return 0;
*/
return top == 0;
}
02.2 中缀表达法转后缀表达法
在02.1中 我们说(1+2)*(3-4)这种常规的表示方法为中缀表达法 而加工后 12+34-* 这种为后缀表达法 那么如何实现 中缀表达法 转化为后缀表达法?
给出算法思想
((1+2)*(3-4))
- 从左至右来处理数据
- 当遇到左括号时,忽略它
- 当遇到数值时,直接输出
- 当遇到操作符时 将操作符入栈
- 当遇到右括号时,出栈栈顶的操作符
代码具体实现
#include <stdio.h>
#include <string.h>
char stack[512];
int top = 0;
void push(char c);
char pop(void);
int is_empty(void);
int main(void)
{
char str[100];
int i, len;
printf("Please enter a calcuate expression:");
gets(str);
len = strlen(str);
for(i = 0; i < len; i++)
{
if(str[i] == '(')
continue;
else if((str[i] >= '0') && (str[i] <= '9'))
printf("%c", str[i]);
else if((str[i] == '+') || (str[i] == '-') || (str[i] == '*'))
push(str[i]);
else if(str[i] == ')')
printf("%c", pop());
}
printf("\n");
return 0;
}
void push(char c)
{
stack[top++] = c;
}
char pop(void)
{
return stack[--top];
}
int is_empty(void)
{
/*
if(top == 0)
return 1;
else
return 0;
*/
return top == 0;
}
02.3 括号匹配
问题引入——你能在四则运算中准确地找到左括号对应的右括号吗!
示例: a[6]=(())()
1-2
0-3
4-5
算法思想:从左往右找 (遇到左括号先忽略) 遇到右括号开始找最近的未被匹配的左括号
程序上就是:左括号入栈 遇到右括号出栈
如何把编号打进去?
将编号代替左括号入栈
编程实现
#include <stdio.h>
#include <string.h>
int stack[512];
int top = 0;
void push(int c);
int pop(void);
int is_empty(void);
int main(void)
{
char str[100];
int i, len;
printf("Please enter a calculate expression:");
gets(str);
len = strlen(str);
for(i = 0; i < len; i++)
{
if(str[i] == '(')
push(i);
else if(str[i] == ')')
printf("%d %d\n", pop(), i);
}
return 0;
}
void push(int c)
{
stack[top++] = c;
}
int pop(void)
{
return stack[--top];
}
int is_empty(void)
{
/*
if(top == 0)
return 1;
else
return 0;
*/
return top == 0;
}
02.4 十进制转换为二进制
问题引入——如何将十进制13转换为二进制?
算法思想:
1.判断n是不是为0 (n!=0),n%2 更新n的值(n=n/2)
2.重复第一步的操作,直到运行为n=0时为止
13
13%2 = 1 13/2 = 6
6%2 = 0 6/2 = 3
3%2=1 3/2=1
1%2 =1 1/2 = 0
3.只要栈不为空,就弹出栈顶内容,打印显示就是我们转换的结果
编程实现
#include <stdio.h>
int stack[512];
int top = 0;
void push(int c);
int pop(void);
int is_empty(void);
int main(void)
{
int num;
printf("Please enter an integer in decimal:");
scanf("%d", &num);
while(num)
{
push(num % 2);
num /= 2;
}
while(!is_empty())
printf("%d", pop());
printf("\n");
return 0;
}
void push(int c)
{
stack[top++] = c;
}
int pop(void)
{
return stack[--top];
}
int is_empty(void)
{
/*
if(top == 0)
return 1;
else
return 0;
*/
return top == 0;
}
02.5 回文判定
什么是回文数?
正着写 反着写 都一样的一行字符就是。比如 abccba 12344321
算法思想
1.求出字符串的长度,将前一半的字符依次入栈
2.如果栈不为空,出栈栈顶元素,将其与后半部分的字符串进行比较。如果字符串长度是奇数的话,要跳过中心点的元素,比较中心点后面的元素
3.如果比较的元素是相等的,一直比较 直到栈为空。这时返回是回文,如果比较不等,立刻停止比较,返回非回文。
编程实现
#include <stdio.h>
#include <string.h>
char stack[512];
int top = 0;
void push(char c);
char pop(void);
int is_empty(void);
int is_palindrom(char *pt);
int main(void)
{
char str[100];
printf("Please enter a string:");
gets(str);
if(is_palindrom(str))
printf("str is a palindrom.\n");
else
printf("str is not a palindrom.\n");
return 0;
}
void push(char c)
{
stack[top++] = c;
}
char pop(void)
{
return stack[--top];
}
int is_empty(void)
{
/*
if(top == 0)
return 1;
else
return 0;
*/
return top == 0;
}
int is_palindrom(char *pt)
{
int len, i;
len = strlen(pt);
for(i = 0; i < len/2; i++)
push(pt[i]);
if(len % 2 == 1)
i++;
while(!is_empty())
{
if(pop() == pt[i])
i++;
else
return 0;
}
return 1;
}