树形结构:使用栈实现,快排,先序遍历,归并排序,后序遍历
生活随笔
收集整理的這篇文章主要介紹了
树形结构:使用栈实现,快排,先序遍历,归并排序,后序遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
主要還是學習使用棧模擬實現遞歸:
總結一下,首先通過棧實現遞歸是有規律可行的,這里面涉及整體到部分,一切都是對象的思想,把一個整體看成一個對象,這個對象是數據和操作的集合,定義這些操作,把操作順序按照逆序放入棧中,就可以實現遞歸棧實現的轉化。
在一般的樹里:一個對象有三個操作,一是訪問根的數據,二是訪問左子樹,三是訪問右子樹,二和三可以合成訪問子樹,只要按照實際順序的逆序把操作的放入棧里就行了。
在快排這里例子里:一個對象有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]總結
以上是生活随笔為你收集整理的树形结构:使用栈实现,快排,先序遍历,归并排序,后序遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 树形结构:递归转化为迭代,万能通用方法,
- 下一篇: 树形结构:优先级队列,堆