在外排序中,假设用替换选择法来创建初始的有序段。内存中用到的优先队列规模为5。给定输入序列{5, 19, 25, 45, 30, 24, 15, 60, 16, 27, 1},下列哪组是生成的有序段?
(3分)
A.
run1: 5, 19, 25, 30, 45; run2: 15, 16, 24, 27, 60; run3: 1
B.
run1: 5, 19, 24, 25, 30, 45; run2: 1, 15, 16, 27, 60
C.
run1: 5, 19, 25, 30, 45; run2:1, 15, 16, 24, 27, 60
D.
run1: 5, 19, 24, 25, 30, 45, 60; run2: 1, 15, 16, 27
答案:D.
run1: 5, 19, 24, 25, 30, 45, 60; run2: 1, 15, 16, 27
先把前面5个放在优先队列里面
从输入序列里拿东西出来,放到优先队列里面最小的数字的位置,要是输入序列里拿东西比优先队列里原来的数字小,
这个地方会被框住,就是下一轮之前,都不会去动他了
一开始的输入序列: [24, 15, 60, 16, 27, 1]
内存缓冲: [5, 19, 25, 45, 30, ]
内存缓冲,$$括起来的是找到的最小数字的位置: [$5$, 19, 25, 45, 30, ]
从内存缓冲拿出最小的5,放到输出磁带里面。
输出磁带: [5]
输入序列: [24, 15, 60, 16, 27, 1]
然后从输入序列拿出下一个数字:24,放到内存缓冲刚才空出来的位置
内存缓冲,$$括起来的是找到的最小数字的位置: [$24$, 19, 25, 45, 30, ]
输入序列,第一个被拿走了: [15, 60, 16, 27, 1]
输出磁带: [5]
内存缓冲,$$括起来的是找到的最小数字的位置: [24, $19$, 25, 45, 30, ]
从内存缓冲拿出最小的19,放到输出磁带里面。
输出磁带: [5, 19]
输入序列: [15, 60, 16, 27, 1]
然后从输入序列拿出下一个数字:15,放到内存缓冲刚才空出来的位置
内存缓冲,$$括起来的是找到的最小数字的位置: [24, $(15)$, 25, 45, 30, ]
输入序列,第一个被拿走了: [60, 16, 27, 1]
输出磁带: [5, 19]
内存缓冲,$$括起来的是找到的最小数字的位置: [$24$, (15), 25, 45, 30, ]
从内存缓冲拿出最小的24,放到输出磁带里面。
输出磁带: [5, 19, 24]
输入序列: [60, 16, 27, 1]
然后从输入序列拿出下一个数字:60,放到内存缓冲刚才空出来的位置
内存缓冲,$$括起来的是找到的最小数字的位置: [$60$, (15), 25, 45, 30, ]
输入序列,第一个被拿走了: [16, 27, 1]
输出磁带: [5, 19, 24]
内存缓冲,$$括起来的是找到的最小数字的位置: [60, (15), $25$, 45, 30, ]
从内存缓冲拿出最小的25,放到输出磁带里面。
输出磁带: [5, 19, 24, 25]
输入序列: [16, 27, 1]
然后从输入序列拿出下一个数字:16,放到内存缓冲刚才空出来的位置
内存缓冲,$$括起来的是找到的最小数字的位置: [60, (15), $(16)$, 45, 30, ]
输入序列,第一个被拿走了: [27, 1]
输出磁带: [5, 19, 24, 25]
内存缓冲,$$括起来的是找到的最小数字的位置: [60, (15), (16), 45, $30$, ]
从内存缓冲拿出最小的30,放到输出磁带里面。
输出磁带: [5, 19, 24, 25, 30]
输入序列: [27, 1]
然后从输入序列拿出下一个数字:27,放到内存缓冲刚才空出来的位置
内存缓冲,$$括起来的是找到的最小数字的位置: [60, (15), (16), 45, $(27)$, ]
输入序列,第一个被拿走了: [1]
输出磁带: [5, 19, 24, 25, 30]
内存缓冲,$$括起来的是找到的最小数字的位置: [60, (15), (16), $45$, (27), ]
从内存缓冲拿出最小的45,放到输出磁带里面。
输出磁带: [5, 19, 24, 25, 30, 45]
输入序列: [1]
然后从输入序列拿出下一个数字:1,放到内存缓冲刚才空出来的位置
内存缓冲,$$括起来的是找到的最小数字的位置: [60, (15), (16), $(1)$, (27), ]
输入序列,第一个被拿走了: []
输出磁带: [5, 19, 24, 25, 30, 45]
从内存缓冲拿出最小的60
内存缓冲: [None, (15), (16), (1), (27), ]
输出磁带: [5, 19, 24, 25, 30, 45, 60]
没有最小的可以拿了
输出磁带: [5, 19, 24, 25, 30, 45, 60]
有1个序列,不包括最后的被定住的那些
[[5, 19, 24, 25, 30, 45, 60]]
最后内存的再排序一下,作为最后的run,如果没有就当做没有最后的run
[1, 15, 16, 27]
解这个题目的代码 不过暂时只能解 只有run2 的
这不是真正的替换选择算法 只是我模拟做题过程
根据https://blog.csdn.net/chuanglan/article/details/79043533
修改之后 现在已经可以算 多个run的了
# -*- coding: utf-8 -*-
# @Author : 喵奇葩
class ReplaceSelect:
"""
替换选择的解题代码,不是真正的算法
根据https://blog.csdn.net/chuanglan/article/details/79043533
修改之后 现在已经可以算 多个run的了
"""
# memo_len=3
# input_lst = []
# memo_lst = []
# is_fixed=[]
# now_index = 0
def __init__(self, input_lst, memo_len):
self.input_lst = input_lst
self.memo_lst = []
self.memo_len = memo_len
self.tape = []
self.input_lst_len = len(self.input_lst)
self.now_index = 0
self.sequences = []
# self.is_fixed=[0 for i in range(len((self.input_lst)))]
self.is_fixed = [False for i in range(self.input_lst_len)]
print(f"先把前面{memo_len}个放在优先队列里面")
print("从输入序列里拿东西出来,放到优先队列里面最小的数字的位置,要是输入序列里拿东西比优先队列里原来的数字小,\n"
"这个地方会被框住,就是下一轮之前,都不会去动他了")
for i in range(memo_len):
self.memo_lst.append(self.input_lst[i])
self.now_index += memo_len
# self.run()
print("一开始的输入序列: ", end="")
self.print_input_lst()
# print("一开始的优先队列", self.memo_lst)
self.print_memo()
def run(self):
cnt = 0
while self.now_index < self.input_lst_len:
self.take_min_push_next()
print()
cnt += 1
if cnt > 100:
print("循环太多,可能有错误,检查看看bug")
break
# self.take_min_push_next()
cnt = 0
while self.take_min():
print()
cnt += 1
if cnt > 100:
print("循环太多,可能有错误,检查看看bug")
break
self.show_sequences()
# print("现在输出磁带里有几个递增的序列,就可以数了,还有最后框柱的可能还有一个序列")
self.memo_sort()
def show_sequences(self):
print("输出磁带:",self.tape)
min_num = self.tape[0]
tmp_lst = []
for num in self.tape:
if num >= min_num:
tmp_lst.append(num)
min_num = num
else:
self.sequences.append(tmp_lst)
min_num = num
# tmp_lst.clear()
# 这里是引用 就算push进去了,还是会改变的
# 所以这里写 clear 是错的
tmp_lst = [min_num]
if len(tmp_lst) > 0:
self.sequences.append(tmp_lst)
print(f"有{len(self.sequences)}个序列,不包括最后的被定住的那些")
print(self.sequences)
def print_fixed(self):
"""
一开始是用来标记被框柱的数字的,但是后来看了
https://blog.csdn.net/chuanglan/article/details/79043533
这篇博客 发现他的用()表示的方法更好,所以就用他的方法了
:return:
"""
# print(" "*8,end="")
print("被框柱: ", end="")
# print(self.is_fixed)
for fixed in self.is_fixed:
if fixed:
print(" ^ ", end="")
else:
print(" ", end="")
print()
def take_min(self):
min_index = self.get_min_index()
if min_index == -1:
print("没有最小的可以拿了")
return False
else:
print(f"从内存缓冲拿出最小的{self.memo_lst[min_index]}")
self.tape.append(self.memo_lst[min_index])
# out_num = self.memo_lst[min_index]
self.memo_lst[min_index] = None
# print("优先队列", self.memo_lst)
# self.print_fixed()
self.print_memo()
# print(self.memo_lst)
print("输出磁带:", self.tape)
# print( self.tape)
# self.now_index += 1
return True
def print_memo(self):
cnt = 0
print("内存缓冲: [", end="")
for num in self.memo_lst:
if self.is_fixed[cnt]:
print(f"({num}),", end=" ")
else:
print(str(num) + ",", end=" ")
cnt += 1
print("]")
def take_memo_show(self, min_index):
cnt = 0
print("内存缓冲,$$括起来的是找到的最小数字的位置: [", end="")
for num in self.memo_lst:
if min_index == cnt:
if self.is_fixed[cnt]:
print(f"$({num})$,", end=" ")
else:
print(f"${num}$,", end=" ")
elif self.is_fixed[cnt]:
print(f"({num}),", end=" ")
else:
print(str(num) + ",", end=" ")
cnt += 1
print("]")
def take_min_push_next(self):
min_index = self.get_min_index()
# self.print_memo()
if min_index == -1:
print("没有最小的可以拿了,全都框柱了")
else:
self.take_memo_show(min_index)
print(f"从内存缓冲拿出最小的{self.memo_lst[min_index]},放到输出磁带里面。")
self.tape.append(self.memo_lst[min_index])
print("输出磁带:", self.tape)
print("输入序列: ", end="")
self.print_input_lst()
print(f"然后从输入序列拿出下一个数字:{self.input_lst[self.now_index]},放到内存缓冲刚才空出来的位置")
# todo
push_num = self.input_lst[self.now_index]
out_num = self.memo_lst[min_index]
self.memo_lst[min_index] = self.input_lst[self.now_index]
if out_num > push_num:
self.is_fixed[min_index] = True
# self.memo_lst[min_index]=self.input_lst[self.now_index]
# self.input_lst.pop_front()
# del self.input_lst[0]
self.now_index += 1
self.take_memo_show(min_index)
print("输入序列,第一个被拿走了: ", end="")
self.print_input_lst()
# print("优先队列", self.memo_lst)
# self.print_fixed()
# self.print_memo()
# print(self.memo_lst)
print("输出磁带:", self.tape)
# print( self.tape)
# https://blog.csdn.net/chuanglan/article/details/79043533
def print_input_lst(self):
# for i in range(self.now_index,self.input_lst_len):
# print()
print(self.input_lst[self.now_index: self.input_lst_len])
def memo_sort(self):
print("最后内存的再排序一下,作为最后的run,如果没有就当做没有最后的run")
want_sort_list = []
for num in self.memo_lst:
if num is None: continue
want_sort_list.append(num)
print(sorted(want_sort_list))
def get_min_index(self):
min_index = 0
# if self.is_fixed[0]:min_index=1
# todo 前面有个被框柱的12 我 94 就不会是最小的 ,12), 94, 96
# 此问题已经解决
# todo :[None, (15), 99, 58, ] 这种情况 直接跳过了 有问题啊,把while循环改了,
# 感觉解决问题了,但是后续肯定还有更多问题的
# 先是把定住的那些跳过了
while min_index < self.memo_len:
if self.is_fixed[min_index]:
min_index += 1
elif self.memo_lst[min_index] is None:
min_index += 1
else:
break
# while min_index < self.memo_len and self.is_fixed[min_index]:
# min_index += 1
# while min_index < self.memo_len and self.memo_lst[min_index] is None:
# min_index += 1
#
# while min_index < self.memo_len and self.is_fixed[min_index]:
# min_index += 1
# while min_index < self.memo_len and self.memo_lst[min_index] is None:
# min_index += 1
# print("min_index", min_index)
if min_index == self.memo_len:
# if self.is_fixed[min_index]:
# 全部都被框柱了
if self.now_index < self.input_lst_len:
self.is_fixed = [False for i in range(self.memo_len)]
min_index = 0
# return -1
else:
return -1
for i in range(self.memo_len):
if self.is_fixed[i]: continue
if type(self.memo_lst[i]) != int: continue
# if type(self.memo_lst[min_index]) != int or type(self.memo_lst[i]) != int: continue
try:
if self.memo_lst[min_index] > self.memo_lst[i]:
min_index = i
# https://www.runoob.com/python/python-exceptions.html
except TypeError:
print("self.memo_lst[min_index]", self.memo_lst[min_index])
print("self.memo_lst[i]", self.memo_lst[i])
raise
# https://www.runoob.com/python/python-func-type.html
if self.is_fixed[min_index]: return -1
return min_index
rs = ReplaceSelect([5, 19, 25, 45, 30, 24, 15, 60, 16, 27, 1], 5)
rs.run()
https://kdocs.cn/l/cughpQIh7F6q
[金山文档] 在外排序中,假设用替换选择法来创建初始的有序段。内存中用到的优先队列规模为5。给定输入序列{5, 19, 25, 45, 30, 24, 15, 60, 16, 27, 1},下列哪组是生成的有序段?.xlsx