算法与数据结构

来源:互联网 发布:那个淘宝网站的商品是正品 编辑:程序博客网 时间:2024/06/05 06:02

发现一个特别用心的大神,他对数据结构和算法有很独到细致的理解:

讲解了栈和队列的概念&代码实现。

感谢原博主
http://www.cnblogs.com/yangecnu/p/Introduction-Stack-and-Queue.html

如何使用数组和链表实现栈与队列。
这里写图片描述

这里写图片描述

这里写图片描述

Stack和Queue的应用

Stack这种数据结构用途很广泛,比如编译器中的词法分析器、Java虚拟机、软件中的撤销操作、浏览器中的回退操作,编译器中的函数调用实现等等。

线程堆是操作系型系统分配的一块内存区域。通常CPU上有一个特殊的称之为堆指针的寄存器 (stack pointer) 。在程序初始化时,该指针指向栈顶,栈顶的地址最大。CPU有特殊的指令可以将值Push到线程堆上,以及将值Pop出堆栈。每一次Push操作都将值存放到堆指针指向的地方,并将堆指针递减。每一次Pop都将堆指针指向的值从堆中移除,然后堆指针递增,堆是向下增长的。Push到线程堆,以及从线程堆中Pop的值都存放到CPU的寄存器中。

当发起函数调用的时候,CPU使用特殊的指令将当前的指令指针(instruction pointer),如当前执行的代码的地址压入到堆上。然后CPU通过设置指令指针到函数调用的地址来跳转到被调用的函数去执行。当函数返回值时,旧的指令指针从堆中Pop出来,然后从该指令地址之后继续执行。

当进入到被调用的函数中时,堆指针减小来在堆上为函数中的局部变量分配更多的空间。如果函数中有一个32位的变量分配到了堆中,当函数返回时,堆指针就返回到之前的函数调用处,分配的空间就会被释放。

如果函数有参数,这些参数会在函数调用之前就被分配在堆上,函数中的代码可以从当前堆往上访问到这些参数。

线程堆是一块有一定限制的内存空间,如果调用了过多的嵌套函数,或者局部变量分配了过多的内存空间,就会产生堆栈溢出的错误。
4.2 算术表达式的求值

Stack使用的一个最经典的例子就是算术表达式的求值了,这其中还包括前缀表达式和后缀表达式的求值。E. W. Dijkstra发明了使用两个Stack,一个保存操作值,一个保存操作符的方法来实现表达式的求值,具体步骤如下:

1) 当输入的是值的时候Push到属于值的栈中。

2) 当输入的是运算符的时候,Push到运算符的栈中。

3) 当遇到左括号的时候,忽略

4) 当遇到右括号的时候,Pop一个运算符,Pop两个值,然后将计算结果Push到值的栈中。

这里写图片描述

使用数据结构,讲解了基本的排序算法

大神很用心的用了一些对比动态图,更方便我们的理解。

选择排序、插入排序、希尔排序
http://www.cnblogs.com/yangecnu/p/Introduction-Insertion-and-Selection-and-Shell-Sort.html

合并排序
http://www.cnblogs.com/yangecnu/p/Introduce-Merge-Sort.html

0 0