23 合併K個排序鍊錶

2021-08-29 05:38:17 字數 3968 閱讀 7453

合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。

示例:

輸入:

[  1->4->5,

1->3->4,

2->6

]輸出: 1->1->2->3->4->4->5->6

#偷懶直接複製了以前的堆的**  所有看上去長了點

class priorityqueue:

# priority是設定優先順序 true為大根堆 false為小根堆

#modify為false的話 就僅僅是拷貝了arr陣列 但是不會修改原來陣列的值

#arr表示可以傳入乙個 將裡面的值直接變成優先順序佇列

def __init__(self,priority=true,modify=false,arr=):

#self._arr.clear()

self._arr=

self.priority=priority#設定他的優先順序 true為大根堆 false為小根堆

if not modify:#modify為false的話 就僅僅是拷貝了arr陣列 但是不會修改原來陣列的值

for i in arr:

# print(i,'i')

else:

self._arr=arr

self._index=len(self._arr)-1#指向最後乙個元素

#print('len(self._arr)=', len(self._arr))

self.firstbuildheap()

#index代表要進行向下調整的結點

def isempty(self):

if len(self._arr)>0:

return false

return true

def buildheap(self,index,_arr):

if self._index==-1: #如果堆裡沒有原始 則返回

return

t = _arr[index]

temp = _arr[index].key # temp代表index下標的值

k = (index * 2) + 1 # k代表index的左子樹

lenth = len(_arr) - 1

#print(lenth,'len')

if self.priority:

while k<=lenth:

#print('b')

if k_arr[k + 1].key: # 如果k的左子樹小於length(也就是k還有右子樹)並且它的右子樹大於它

k += 1 # k++ k指向了右子樹

if _arr[k].key > temp: # 如果temp大於當前子樹的最大值(無論左子樹還是右子樹都大於,因為上個判斷已經判斷了左右子樹大小)

break # 直接返回

_arr[index] = _arr[k] # 如果temp不大於左子樹或者右子樹的值 將k結點(index子樹)的值賦給inedx結點值

index = k # 要調整的結點變為k 因為index結點已經判斷完了

k = (k * 2) + 1 # k變成index的左子樹

_arr[index] = t

pass

def firstbuildheap(self):

index=(len(self._arr)//2)-1

while index>=0:

self.buildheap(index,self._arr)

index-=1

def get_arr(self):

return self._arr

def getmaxpriority(self):

if self._index == -1: #如果_index為-1 則堆為空

return

self.__swap(0,self._index,self._arr)#不然交換堆頂元素和最後的元素

maxpriorityvalue=self._arr[self._index] #交換後取得最後乙個元素

self.__remove() #刪除最後乙個元素

return maxpriorityvalue #返回最大值

def __remove(self):

if self._index==-1: #如果_index為-1 則堆為空

return

self._arr.pop() #刪除最後乙個元素

self._index-=1

self.buildheap(0,self._arr)#因為目前堆頂元素是未知的,所以要進行一次調整

return

def insert(self,key,value):

n=node(key,value)

self._index += 1 # index++ index代表了value的下標

index = self._index

if index % 2 == 0:

parent = index // 2 - 1

else:

parent = index // 2 # 獲取index的父節點

temp = self._arr[index].key # 獲取當前帶插入元素的key值

t=self._arr[index] # 獲取當前帶插入元素

if self.priority:

#上濾while parent>=0: #如果沒超過根節點 也就是index的父節點最大只能為0號下標

if temp= 0: # 如果沒超過根節點 也就是index的父節點最大只能為0號下標

if temp > self._arr[parent].key : # 如果下標index的值也就是value小於它的父節點,沒破壞堆序性

break

# print(index,parent)

self._arr[index] = self._arr[parent] # 不然的話將它的父節點的值賦給index

index = parent # index的父節點成為新的待調整結點

if index % 2 == 0:

parent = index // 2 - 1

else:

parent = index // 2 # 取得新index的父節點

self._arr[index] = t # 迴圈結束後將temp也就是value的值給最後停下來的index

return

def __swap(self,i,j,arr):

k=arr[i]

arr[i]=arr[j]

arr[j]=k

class solution(object):

def mergeklists(self, lists):

""":type lists: list[listnode]

:rtype: listnode

"""l=none

node=listnode(0)

pq = priorityqueue(priority=false)

for i in range(len(lists)):

while true:

if not lists[i]:

break

pq.insert(lists[i].val,lists[i])

lists[i]=lists[i].next

#使用乙個小根堆

while not pq.isempty():

temp=pq.getmaxpriority()

node.next=temp.value

if not l:

l=node.next

node=node.next

node.next=none

return l

23 合併K個排序鍊錶

合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。採用分治法的思想,將 k 個排序鍊錶先合併為 k 2 個鍊錶。依次迴圈,直至合併為1個鍊錶為止。注意 從 k 到 k 2 時,如何定義索引,將每兩個鍊錶合併,而且必須符合奇數 偶數個鍊錶的情況。解決辦法 k n 1 2 list...

23 合併K個排序鍊錶

合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例 輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 暴力法 將所有的節點放在乙個陣列中,然後對陣列排序,最後遍歷陣列,組建新的鍊錶。definition for singly linked list...

23 合併K個排序鍊錶

題目.很有意思 第一想法就是使用最小堆或者比較樹,這個方法當然是可以的,但是用go語言難寫,尤其是比較樹。採用歸併排序的思想倒是很快,每次比較都需要比較o n 次,一共log2k次 package main import fmt type listnode struct func printlist...