主要还是学习使用栈模拟实现递归:

总结一下,首先通过栈实现递归是有规律可行的,这里面涉及整体到部分,一切都是对象的思想,把一个整体看成一个对象,这个对象是数据和操作的集合,定义这些操作,把操作顺序按照逆序放入栈中,就可以实现递归栈实现的转化。

在一般的树里:一个对象有三个操作,一是访问根的数据,二是访问左子树,三是访问右子树,二和三可以合成访问子树,只要按照实际顺序的逆序把操作的放入栈里就行了。

在快排这里例子里:一个对象有2个操作,一是访问左子树,二是是访问右子树,我们把这2个逆序放入栈里。注意实际的例子和树结构的例子有区别,树是已经划分为树了,实际的例子,还有一个划分子问题,也就是形成树的过程,这个是不包含在前面万能模板里面的。

快排可以看成先序遍历的例子。

# -*- coding: utf-8 -*-def partition(arr,low,high):# 这时另外一种考虑方式,而且他是不需要额外空间的,他只使用一个指针来区分小于基准和大于基准的# pointer_less_than代表这个指针的左边全部都是小于基准的(包括自己,不包括首元素)# 然后从左往右扫描,遇到小于基准的元素,就把小于基准元素区域的后面紧接着的一个元素和他交换# 那么小于基准元素区域就多了一个元素,。。。就这样小于基准的元素就连在了一起# 首元素是基准元素,小于基准元素区域块,大于基准元素区域块,现在分成了三个部分# 把首元素和小于基准元素区域块最后一个元素交换,那三部分就变成,小于的,基准,大于的# 刚开始小于基准的元素为0,暂且指向首位值pointer_less_than = low# 然后一次扫描后面所有元素for i in range(pointer_less_than +1,high+1):# 遇到小于基准的,就把小于基准元素区域的后面紧接着的一个元素和他交换,小于的块相当于也更新了if arr[i] < arr[low] :pointer_less_than +=1arr[pointer_less_than],arr[i]=arr[i],arr[pointer_less_than]#  把首元素和小于基准元素区域块最后一个元素交换,那三部分就变成,小于的,基准,大于的       arr[low],arr[pointer_less_than] = arr[pointer_less_than],arr[low]return pointer_less_thanclass guide:def __init__(self,left =None,right =None):self.left =leftself.right =rightdef quick_sort(arr):stack =[guide(0,len(arr)-1),]while stack:# 弹出子问题pointer = stack.pop()# 划分子问题,这个是必须操作,划分子问题操作,把对原问题的访问隐含在里面index = partition(arr,pointer.left,pointer.right)# 以下是操作的处理,快排在划分子问题之后,只有一个操作,访问子问题# 按照逆序放入栈if index+1 <= pointer.right:stack.append(guide(index+1,pointer.right))if pointer.left <= index-1:stack.append(guide(pointer.left,index-1))arr = [7,9,6,5,4,8,3,1]
print(arr)
quick_sort(arr)
print(arr)runfile('D:/share/test/stack_recursion.py', wdir='D:/share/test')
[7, 9, 6, 5, 4, 8, 3, 1]
[1, 3, 4, 5, 6, 7, 8, 9]

再具一个归并排序的例子:归并排序,每一个对象有3个操作,一是处理左子树,二是处理右子树,三是合并二者的结果,注意这里划分子问题这一步,属于必须操作的步骤,每一个对象首先操作的步骤。

归并是先处理左子树,再处理右子树,然后处理原问题,是典型的后序遍历

# 如下是针对两个已排序的数组合并成一个有序数组的排列方法,为最基本的双针模型
def MergeArry(arr,left,right):i =leftmiddle = left + (right-left)//2j =middle +1result =[]while i <= middle and j <= right:if arr[i] <= arr[j]:result.append(arr[i])i +=1else:result.append(arr[j])j += 1result += arr[i:middle+1]result += arr[j:right+1]arr[left:right+1] = result[:]
class path:def __init__(self,left =None,right=None,opt =None):self.left =leftself.right = right# True是处理子问题,False为合并self.opt =optdef MergeSort2(arr):stack =[path(0,len(arr)-1,True),]while stack:# 弹出子问题pointer = stack.pop()# 子问题的划分,这个是必须的操作,首先是划分子问题middle = pointer.left + (pointer.right-pointer.left)//2# 归并排序有两个操作:一是访问子问题,二是合并原问题,为了操作方便,改写了函数原地操作# 如果操作是访问子问题if pointer.opt:# 对于一个问题,先解决左子问题,再解决右子问题,再把两个子问题合并,逆序放入if pointer.left<pointer.right:stack.append(path(pointer.left,pointer.right,False))                stack.append(path(middle+1,pointer.right,True))stack.append(path(pointer.left,middle,True))# 如何操作是合并,就执行合并操作else:MergeArry(arr,pointer.left,pointer.right)arr = [1,9,11,12,4,5,6,7,99]
MergeSort2(arr)
print(arr)runfile('D:/share/test/stack_recursion.py', wdir='D:/share/test')
[1, 4, 5, 6, 7, 9, 11, 12, 99]

树形结构:使用栈实现,快排,先序遍历,归并排序,后序遍历相关推荐

  1. 已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法...

    已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法 #define N 10 //二叉树节点的个数 char postorderstr[]={};//后序序列 char i ...

  2. 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

    二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或 ...

  3. 栈的应用--中序表达式转后序表达式

    栈的应用--中序表达式转后序表达式 infix : a+b*c+(d*e+f)*g postfix : abc*+de*f+g*+ 有以下四种情况: 操作数->直接输出 操作符->将栈顶输 ...

  4. 树形结构:迭代方式遍历树,宽度优先,先序遍历,中序遍历,后序遍历

    迭代的方式处理树,就必须清楚你将要访问的顺序,对应的就是指针怎么走,你必须很清楚 树的宽度优先搜索,他是一层一层的访问,就搞不清楚怎么划分子问题了,但是你访问的顺序 你很清楚,那么就使用迭代的方式实现 ...

  5. 有苦有乐的算法 --- 用栈和递归的方式实现二叉树的前序遍历、中序遍历、后序遍历

    前序遍历 递归方式: public static void pre(Node head) {if (head == null) {return;}System.out.println(head.val ...

  6. 数据结构之【树形结构】复习题

    第五章        树形结构 一.选择题 1.已知一算术表达式的中缀形式为 A+B*C-D/E,后缀形式为ABC*+DE/-,其前缀形式为(D    ) A.-A+B*C/DE       B.-A ...

  7. 排序 之 快排、归并、插入 - 时间复杂度----掌握思想和过程

    俗话说:天下武功无坚不破,唯快不破.对于算法当然也是要使用时间最短.占用空间最小的算法来实现了. 注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或 ...

  8. 【排序算法】插入、选择、堆排、快排、归并、计数

    一.插入排序 insertSort 1.实现 2.性能分析 3.折半插入排序(了解) 二.希尔排序 ShellSort 1.原理 2.实现 3.性能分析 三.选择排序 selectSort 1.原理 ...

  9. 快速提升网站排名_使用快排优化的方法

    确定自己网站适不适合做快排 好多小伙伴想为自己网站做一做快排,但是又不知道自己网站适不适合,首先,大家都知道选好关键词的重要性,想实现投入和产出的最大化,建设网站前选好合适的关键词是非常必要的.找到网 ...

  10. 在php中冒泡排序,php中实现快排与冒泡排序

    快排 function quicksort($str){ if(count($str)<=1) return $str;//如果个数不大于一,直接返回 $key=$str[0];//取一个值,稍 ...

最新文章

  1. HDU 1877 另一个版本 A+B
  2. H3C静态路由、Track与BFD联动配置举例
  3. 可视化自编码器训练结果
  4. WEB请求处理六:浏览器HTTP协议漫谈
  5. 火狐web开发清楚缓存_如何使用Firefox的Web开发工具
  6. mysql 无符号 负数_mysql – BETWEEN使用负值和无符号整数
  7. 2017/07/27 工作日志
  8. settimeout在各个浏览器的最小时间
  9. java IDEA 打包发布
  10. 近视矫正手术:准分子激光,飞秒,全飞秒
  11. python处理word文档格式_python处理word文档(docxtpl 中文说明文档)
  12. 用vue-cli3导入外部的iconfont.css图标样式遇到的坑:These relative modules were not found:...
  13. 产品数据管理(PDM)技术说明书
  14. CSS总结1-来自freecode
  15. 容安馆札记 588则 笺疏
  16. c语言中begin用法,C++ deque cbegin()用法及代码示例
  17. git文件夹不显示绿勾
  18. 跨国传输大数据,如何高效又安全?
  19. IOS破解软件,比较全的网站。
  20. Protocol Buffers和JSON相互转换

热门文章

  1. 领域驱动设计-什么是领域驱动设计和怎么使用它
  2. 前端笔试题(附答案)
  3. java Mina sftp_java – 使用Apache Mina作为模拟/内存SFTP服务器进行单元测试
  4. deepin系统中.txt文件图标显示内容问题_深度系统Deepin 20最新正式版发布:从DDE到应用全面升级-Deepin 20,深度系统 ——快科技(驱动之家旗下媒体)-...
  5. php采集一言代码_PHP简单实现一言 / 随机一句功能
  6. 集合在枚举数实例化后进行了修改_(编程知识)C# 枚举与位枚举
  7. uniapp 页面下次渲染完成后执行:this.$nextTick
  8. spring mvc字符编码过滤器 CharacterEncodingFilter ,添加例外url
  9. 用Location对象和history对象修改页面url
  10. android mock测试资源,Android 单元测试 --Mock 及 Mockito