目录
一、 AdjGraph
'''在教材源码AdjGraph.py,BFS1.py,DFS1.py的基础上,改编成单链表的形式实现邻接表。
1、先分别定义顶点结点,和边结点。
2、顶点结点存放于Python的list中,每个顶点结点作为单链表的头结点,指向自身所连的边结点,形成一条单链表。
3、同时改编图创建、图显示、广度优先遍历、深度优先遍历的方法。'''
from collections import deque
MAXV = 100 #表示最多顶点个数
INF = 0x3f3f3f3f #表示∞
class ArcNode: #边结点
def __init__(self, adjv, w, adjvr): #构造方法
self.next = adjv #下一个邻接点
self.weight = w #边的权值
self.adjvex = adjvr #邻接点
class verNode: #顶点结点
def __init__(self, adjv): #构造方法
self.next = adjv #下一个邻接点
class AdjGraph: #图邻接表类
def __init__(self, n=0, e=0): #构造方法
self.adjlist = [] #邻接表数组
self.vexs = [] #存放顶点信息,暂时未用
self.n = n #顶点数
self.e = e #边数
def CreateAdjGraph(self, a, n, e): # 通过数组a、n和e建立图的邻接表
self.n = n #置顶点数和边数
self.e = e
for i in range(n): #检查边数组a中每个元素
adi = verNode(None) #存放顶点i的邻接点
jun = adi
for j in range(n):
if a[i][j] != 0 and a[i][j] != INF: #存在一条边
p = ArcNode(None, a[i][j], j) #创建<j,a[i][j]>出边的结点p
jun.next = p #将结点p添加到adi中
jun = p
self.adjlist.append(adi)
def DispAdjGraph(self): #输出图的邻接表
for i in range(self.n): #遍历每一个顶点i
print(" [%d]" % (i), end='')
jun = self.adjlist[i].next
while jun != None:
print("->(%d,%d)" % (jun.adjvex, jun.weight), end='')
jun = jun.next
print("->∧")
def BFS(G, v): #邻接表G中从顶点v出发的广度优先遍历
MAXV = 100 #全局变量,表示最多顶点个数
visited = [0] * MAXV
qu = deque() #将双端队列作为普通队列qu
print(v, end=" ") #访问顶点v
visited[v] = 1 #置已访问标记
qu.append(v) #v进队
while len(qu) > 0: #队不空循环
v = qu.popleft() #出队顶点v
m = G.adjlist[v]
while m.next != None:
w = m.next.adjvex
m = m.next
if visited[w] == 0: #若w未访问
print(w, end=" ") #访问顶点w
visited[w] = 1 #置已访问标记
qu.append(w) #w进队
def DFS(G, v): #邻接表G中从顶点v出发的深度优先遍历
MAXV = 100 #全局变量,表示最多顶点个数
visited = [0] * MAXV
print(v, end=' ') #访问顶点v
visited[v] = 1 #置已访问标记
m = G.adjlist[v]
while m.next != None: #处理顶点v的所有出边顶点j
w = m.next.adjvex
if visited[w] == 0:
DFS(G, w) #若w顶点未访问,递归访问它
m = m.next
if __name__ == '__main__':
G = AdjGraph()
n, e = 5, 5
a = [[0, 8, INF, 5, INF], [INF, 0, 3, INF, INF], [INF, INF, 0, INF, 6],
[INF, INF, 9, 0, INF], [INF, INF, INF, INF, 0]]
G.CreateAdjGraph(a, n, e)
G.DispAdjGraph()
'''
G = AdjGraph()
n, e = 6, 7
a = [[0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1], [0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0]]
G.CreateAdjGraph(a, n, e)
print("图G")
G.DispAdjGraph()
print("BFS:", end=' ')
BFS(G, 0)
'''
'''
G = AdjGraph()
n, e = 6, 7
a = [[0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1], [0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0]]
G.CreateAdjGraph(a, n, e)
print("图G")
G.DispAdjGraph()
print("DFS ", end=' ')
DFS(G, 0)'''
二、BinSearch
def BinSearch(R, k): # 拆半查找非递归算法
n = len(R)
for x in range(len(k)):
i = 0
f = True
ls = []
low, high = 0, n - 1
while low <= high: # 当前区间非空时
i += 1
mid = (low + high) // 2 # 求查找区间的中间位置
ls.append(R[mid])
if k[x] == R[mid]: # 查找成功返回其序号mid
print('查找{},查找次数为{}次,查找过程中比较的数据为:{}'.format(
k[x], i,
str(ls)[1:-1])) # 找到后返回其序号i
f = False
if k[x] < R[mid]: # 继续在R[low..mid-1]中查找
high = mid - 1
else: # k>R[mid]
low = mid + 1 # 继续在R[mid+1..high]中查找
if f:
print('未找到{},查找次数为{}次,查找过程中比较的数据为:{}'.format(
k[x], i,
str(ls)[1:-1])) # 找不到的情况
if __name__ == '__main__':
R = [
1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 17, 18, 19, 20, 24, 25, 26, 30,
35, 40, 45, 50, 100
]
K = [2, 8, 20, 30, 50, 5, 15, 33, 110]
BinSearch(R, K)
print()
R = [
2, 3, 5, 7, 8, 10, 12, 15, 18, 20, 22, 25, 30, 35, 40, 45, 50, 55, 60,
80, 100
]
K = [22, 8, 80, 3, 100, 1, 13, 120]
BinSearch(R, K)
三、BTree
from collections import deque
class BTNode: # 二叉链中结点类
def __init__(self, d=None): # 构造方法
self.data = d # 结点值
self.lchild = None # 左孩子指针
self.rchild = None # 右孩子指针
class BTree: # 二叉树类
def __init__(self, d=None): # 构造方法
self.b = None # 根结点指针
def SetRoot(self, r): # 设置根结点为r
self.b = r
def DispBTree(self): # 返回二叉链的括号表示串
return self._DispBTree1(self.b)
def _DispBTree1(self, t): # 被DispBTree方法调用
if t == None: # 空树返回空串
return ""
else:
bstr = t.data # 输出根结点值
if t.lchild != None or t.rchild != None:
bstr += "(" # 有孩子结点时输出"("
bstr += self._DispBTree1(t.lchild) # 递归输出左子树
if t.rchild != None:
bstr += "," # 有右孩子结点时输出","
bstr += self._DispBTree1(t.rchild) # 递归输出右子树
bstr += ")" # 输出")"
return bstr
def FindNode(self, x): # 查找值为x的结点算法
return self._FindNode1(b, x)
def _FindNode1(self, t, x): # 被FindNode方法调用
if t == None:
return None # t为空时返回null
elif t.data == x:
return t # t所指结点值为x时返回t
else:
p = self._FindNode1(t.lchild, x) # 在左子树中查找
if p != None:
return p # 在左子树中找到p结点,返回p
else:
return self._FindNode1(t.rchild, x) # 返回在右子树中查找结果
def Height(self): # 求二叉树高度的算法
return self._Height1(b)
def _Height1(self, t): # 被Height方法调用
if t == None:
return 0 # 空树的高度为0
else:
lh = self._Height1(t.lchild) # 求左子树高度lchildh
rh = self._Height1(t.rchild) # 求右子树高度rchildh
return max(lh, rh) + 1
def PreOrder(bt): # 先序遍历的递归算法
PreOrder1(bt.b)
def PreOrder1(t): # 被PreOrder方法调用
if t != None:
print(t.data, end=' ') # 访问根结点
PreOrder1(t.lchild) # 先序遍历左子树
PreOrder1(t.rchild) # 先序遍历右子树
def InOrder(bt): # 中序遍历的递归算法
InOrder1(bt.b)
def InOrder1(t): # 被InOrder方法调用
if t != None:
InOrder1(t.lchild) # 中序遍历左子树
print(t.data, end=' ') # 访问根结点
InOrder1(t.rchild) # 中序遍历右子树
def PostOrder(bt): # 后序遍历的递归算法
PostOrder1(bt.b)
def PostOrder1(t): # 被PostOrder方法调用
if t != None:
PostOrder1(t.lchild) # 后序遍历左子树
PostOrder1(t.rchild) # 后序遍历右子树
print(t.data, end=' ') # 访问根结点
def LevelOrder(bt): # 层次遍历的算法
qu = deque() # 将双端队列作为普通队列qu
qu.append(bt.b) # 根结点进队
while len(qu) > 0: # 队不空循环
p = qu.popleft() # 出队一个结点
print(p.data, end=' ') # 访问p结点
if p.lchild != None: # 有左孩子时将其进队
qu.append(p.lchild)
if p.rchild != None: # 有右孩子时将其进队
qu.append(p.rchild)
if __name__ == '__main__':
b = BTNode('A') # 建立各个结点
p1 = BTNode('B')
p2 = BTNode('C')
p3 = BTNode('D')
p4 = BTNode('E')
p5 = BTNode('F')
p6 = BTNode('G')
b.lchild = p1 # 建立结点之间的关系
b.rchild = p2
p1.lchild = p3
p3.rchild = p6
p2.lchild = p4
p2.rchild = p5
bt = BTree()
bt.SetRoot(b)
print("bt:", end=' ')
print(bt.DispBTree())
x = 'X'
p = bt.FindNode(x)
if p != None:
print("bt中存在" + x)
else:
print("bt中不存在" + x)
print("bt的高度=%d" % (bt.Height()))
print("先序序列:", end=' ')
PreOrder(bt)
print()
print("中序序列:", end=' ')
InOrder(bt)
print()
print("后序序列:", end=' ')
PostOrder(bt)
print()
print("层次序列:", end=' ')
LevelOrder(bt)
print()
四、BreeSons
'''假设二叉树中每个结点值为单个字符,采用二叉链存储结构存储,设计一个算法,计算一棵给定二叉树bt中的所有单分支结点个数。'''
class BTNode: # 二叉链中结点类
def __init__(self, d=None): # 构造方法
self.data = d # 结点值
self.lchild = None # 左孩子指针
self.rchild = None # 右孩子指针
class BTree: # 二叉树类
def __init__(self, d=None): # 构造方法
self.b = None # 根结点指针
def SetRoot(self, r): # 设置根结点为r
self.b = r
def Sons(self):
return self._Sons(self.b)
def _Sons(self, t):
if not t:
return 0
elif (not t.lchild and t.rchild) or (t.lchild and not t.rchild):
return self._Sons(t.lchild) + self._Sons(t.rchild) + 1
else:
return self._Sons(t.lchild) + self._Sons(t.rchild)
if __name__ == '__main__':
b = BTNode('A') # 建立各个结点
p1 = BTNode('B')
p2 = BTNode('C')
p3 = BTNode('D')
p4 = BTNode('E')
p5 = BTNode('F')
p6 = BTNode('G')
b.lchild = p1 # 建立结点之间的关系
b.rchild = p2
p1.lchild = p3
p3.rchild = p6
p2.lchild = p4
p2.rchild = p5
bt = BTree()
bt.SetRoot(b)
print("bt的单分支节点个数=%d" % (bt.Sons()))
五、BTreeWidge
'''假设二叉树采用二叉链存储结构,且所有结点值均不相同。设计一个算法,求二叉树的宽度(即二叉树中结点个数最多的那一层的结点个数)。'''
from collections import deque
class BTNode: # 二叉链中结点类
def __init__(self, d=None): # 构造方法
self.data = d # 结点值
self.lchild = None # 左孩子指针
self.rchild = None # 右孩子指针
class BTree: # 二叉树类
def __init__(self, d=None): # 构造方法
self.b = None # 根结点指针
def SetRoot(self, r): # 设置根结点为r
self.b = r
def Height(self): # 求二叉树高度的算法
return self._Height1(b)
def _Height1(self, t): # 被Height方法调用
if not t:
return 0 # 空树的高度为0
else:
lh = self._Height1(t.lchild) # 求左子树高度lchildh
rh = self._Height1(t.rchild) # 求右子树高度rchildh
return max(lh, rh) + 1
def Width(self):
sw = 0
for i in range(1, self.Height() + 1):
p = KCount1(self, i)
if p > sw:
sw = p
return sw
class QNode: # 队列元素类
def __init__(self, l, p): # 构造方法
self.lev = l # 结点的层次
self.node = p # 结点引用
def KCount1(bt, k): # 求二叉树第k层结点个数
cnt = 0 # 累计第k层结点个数
qu = deque() # 定义一个队列qu
qu.append(QNode(1, bt.b)) # 根结点(层次为1)进队
while len(qu) > 0: # 队不空循环
p = qu.popleft() # 出队一个结点
if p.lev > k: # 当前结点的层次大于k,返回
return cnt
if p.lev == k:
cnt += 1 # 当前结点是第k层的结点,cnt增1
else: # 当前结点的层次小于k
if p.node.lchild: # 有左孩子时将其进队
qu.append(QNode(p.lev + 1, p.node.lchild))
if p.node.rchild: # 有右孩子时将其进队
qu.append(QNode(p.lev + 1, p.node.rchild))
return cnt
if __name__ == '__main__':
b = BTNode('A') # 建立各个结点
p1 = BTNode('B')
p2 = BTNode('C')
p3 = BTNode('D')
p4 = BTNode('E')
p5 = BTNode('F')
p6 = BTNode('G')
b.lchild = p1 # 建立结点之间的关系
b.rchild = p2
p1.lchild = p3
p3.rchild = p6
p2.lchild = p4
p2.rchild = p5
bt = BTree()
bt.SetRoot(b)
print("bt的高度=%d" % (bt.Height()))
print("bt的宽度=%d" % (bt.Width()))
六、CSqQueue
'''对于CSqQueue.py,增加以下3项基本运算
1)增加一个数据成员变量priority,入队时指定元素的priority,
使得出队列时priority最大的元素最先出列
2)求队列中所有元素之和
3)display队列中所有元素的值
'''
MaxSize = 100 #全局变量,假设容量为100
class CSqQueue: #循环队列类
def __init__(self): #构造方法
self.priority = [None] * MaxSize #存放队列中元素优先级
self.data = [None] * MaxSize #存放队列中元素
self.front = 0 #队头指针
self.rear = 0 #队尾指针
def empty(self): #判断队列是否为空
return self.front == self.rear
def push(self, p, e): #元素e进队
assert (self.rear + 1) % MaxSize != self.front #检测队满
self.rear = (self.rear + 1) % MaxSize
self.data[self.rear] = e
self.priority[self.rear] = p
'''
def pop(self): #出队元素
assert not self.empty() #检测队空
self.front = (self.front + 1) % MaxSize
return self.data[self.front]
'''
def pop(self):
assert not self.empty() #检测队空
datap = dict()
if self.rear < self.front:
self.rear += MaxSize
for i in range(self.rear - self.front):
datap[self.priority[self.front + 1 + i]] = self.data[self.front +
1 + i]
data_p = sorted(datap.items(), key=lambda x: x[0], reverse=True)
for i in range(1, self.rear - self.front + 1):
self.data[self.front + i] = data_p[i - 1][1]
self.priority[self.front + i] = data_p[i - 1][0]
self.front = (self.front + 1) % MaxSize
return self.data[self.front]
def gethead(self): #取队头元素
assert not self.empty() #检测队空
head = (self.front + 1) % MaxSize #求队头元素的位置
return self.data[head]
# 例3.11增加的方法
def size(self): #返回队中元素个数
return ((self.rear - self.front + MaxSize) % MaxSize)
def sumall(self): # 求队列中所有元素之和
assert self.front != self.rear #检测空栈的异常
s = 0
self.p = self.front + 1
for i in range(self.size()):
s = s + self.data[self.p] # type:ignore
self.p = (self.p + 1) % MaxSize
return s
def display(self): # display队列中所有元素的值
self.p = self.front + 1
for i in range(self.size()):
print(self.data[self.p], end=' ') # type:ignore
self.p = (self.p + 1) % MaxSize
print()
if __name__ == '__main__':
qu = CSqQueue()
qu.push(2, 6)
qu.push(3, 7)
qu.push(1, 5)
qu.display()
print(qu.empty())
print(qu.gethead())
print("队列中元素总和为{}".format(qu.sumall()))
print("元素个数=%d" % (qu.size()))
while not qu.empty():
print(qu.pop(), end=' ')
print()
print("元素个数=%d" % (qu.size()))
七、LinkList
'''
题目二:设计整数单链表的基本运算程序,并用相关数据进行测试
'''
# 单链表结点类
class LinkNode:
# 构造函数
def __init__(self, data=None) -> None:
self.data = data # data属性
self.next = None # next属性
# 线性表的单链表
class LinkList:
# 构造函数
def __init__(self) -> None:
self.head = LinkNode() # 头结点head
self.head.next = None
# 头插法——由数组a整体建立链表
def CreateListF(self, a):
for i in range(len(a)):
s = LinkNode(a[i]) # 新建存放a[i]元素的结点s
s.next = self.head.next # 将s结点插入到开始结点之前,头结点之后
self.head.next = s
# 尾插法——由数组a整体建立链表
def CreateListR(self, a):
t = self.head
for i in range(len(a)):
s = LinkNode(a[i]) # 新建存放a[i]元素的结点s
t.next = s # 将s结点插入t结点之后
t = s
# 返回序号为i的结点
def geti(self, i):
p = self.head
j = -1
while (j < i and p is not None):
j += 1
p = p.next
return p
# 在线性表的末尾添加一个元素e
def Add(self, e):
s = LinkNode(e) #新建存放e元素的结点s
p = self.head
while p.next:
p = p.next
p.next = s
# 返回链表长度
def getsize(self):
p = self.head
count = 0
while p.next:
count += 1
p = p.next
return count
# 求序号为i的元素
def __getitem__(self, i):
return self.geti(i).data
# 设置序号为i的元素
def __setitem__(self, i, e):
self.geti(i).data = e
# 查找第一个为e的元素的序号
def GetNo(self, e):
j = 0
p = self.head.next
while p.data != e and p:
j += 1
p = p.next
if p:
return j
return -1 # 未找到时返回-1
# 在线性表中序号i位置插入元素e
def Insert(self, i, e):
s = LinkNode(e) #新建存放e元素的结点s
p = self.geti(i - 1)
s.next = p.next
p.next = s
# 在线性表中删除序号i位置的元素
def Delete(self, i):
p = self.geti(i - 1)
p.next = p.next.next # 删除p结点的后继结点
# 输出线性表
def display(self):
p = self.head.next
while p:
print(p.data, end=' ')
p = p.next
print()
# 测试数据
if __name__ == '__main__':
L = LinkList()
for i in range(1, 6):
L.Add(i)
print("L: ", end='')
L.display()
print("序号为2的元素=%d" % (L[2]))
print("设置序号为2的元素为8")
L[2] = 8
print("序号为2的元素=%d" % (L[2]))
n = L.getsize()
print("size=%d" % (n))
for i in range(0, n):
print("删除%d序号的元素" % (0))
L.Delete(0)
print("L: ", end='')
L.display()
print("size=%d" % (L.getsize()))
L1 = LinkList()
a = [1, 2, 3, 4, 1]
L1.CreateListR(a)
print("L: ", end='')
L1.display()
print("序号为2的元素=%d" % (L1[2]))
print("设置序号为2的元素为58")
L1[2] = 58
print("序号为2的元素=%d" % (L1[2]))
i = 4
x = 10
print("在序号%d处插入%d" % (i, x))
L1.Insert(i, x)
print("L: ", end='')
L1.display()
i = 4
print("删除序号%d处元素" % (i))
L1.Delete(i)
print("L: ", end='')
L1.display()
x = 20
print("添加%d元素" % (x))
L1.Add(x)
print("L: ", end='')
L1.display()
print("元素1的序号是%d" % (L1.GetNo(1)))
八、LinkStack
'''題目一:
将LinkStack.py改编成双向链表的栈,并增加以下两项运算:
1)求栈中所有元素之和
2)display栈中所有元素的值
'''
class LinkNode: #双链表结点类
def __init__(self, data=None): #构造方法
self.data = data #data域
self.next = None #next域
self.prior = None #prior域
class LinkStack: #链栈类
def __init__(self): #构造方法
self.head = LinkNode() #头结点head
self.head.next = None
self.head.prior = None
def empty(self): #判断栈是否为空
if self.head.next == None:
return True
return False
def push(self, e): #元素e进栈 头插法
p = LinkNode(e)
p.next = self.head.next
if self.head.next != None: #修改头结点的非空后继结点的prior
self.head.next.prior = p
self.head.next = p # type:ignore
p.prior = self.head # type:ignore 修改p结点的prior
def pop(self): #元素出栈
assert self.head.next != None #检测空栈的异常
p = self.head.next
p.prior.next = p.next #修改p结点的前驱结点的next
if p.next != None: #修改p结点非空后继结点的prior
p.next.prior = p.prior
return p.data
def gettop(self): #取栈顶元素
assert self.head.next != None #检测空栈的异常
return self.head.next.data
def sumall(self): #求栈中所有元素之和
assert self.head.next != None #检测空栈的异常
p = self.head.next
sumall = 0
while p != None:
sumall += p.data
p = p.next
return sumall
def display(self): # 打印栈中所有元素的值
p = self.head.next
while p:
print(p.data, end=' ')
p = p.next
print()
if __name__ == '__main__':
st = LinkStack()
st.push(1)
st.push(2)
st.push(3)
st.push(4)
print(st.empty())
print(st.gettop())
print("栈中所有元素为", end=' ')
st.display()
print("栈中元素总和为:{}".format(st.sumall()))
print("出栈顺序:", end=' ')
while not st.empty():
print(st.pop(), end=' ')
print()
九、Reverse
# 2.用递归的方法编程实现输入的数字逆序输出:Reverse(n)
import sys
sys.setrecursionlimit(100000) #递归的深度这里设置为十万
'''
def Reverse(n):
if n != 0:
print(n % 10)
return Reverse(n // 10)
'''
def Reverse(n):
print(n % 10, end='')
if n // 10 != 0:
Reverse(n // 10)
Reverse(120340)
十、SeqSearch
def SeqSearch1(R, k): # 顺序查找算法1
n = len(R)
for x in range(len(k)):
i = 0
ls = []
while i < n and R[i] != k[x]:
ls.append(R[i])
i += 1 # 从表头往后找
if i > n:
print('未找到{},查找次数为{}次,查找过程中比较的数据为:{}'.format(
k[x], i,
str(ls)[1:-1]))
else:
print('查找{},查找次数为{}次,查找过程中比较的数据为:{}'.format(
k[x], i,
str(ls)[1:-1])) # 找到后返回其序号i
def SeqSearch2(R, k): # 顺序查找算法2
n = len(R)
R.append(0)
for x in range(len(k)):
i = 0
ls = []
R[n] = k[x] # 添加哨兵
while R[i] != k[x]:
ls.append(R[i])
i += 1 # 从表头往后找
if i == n:
print('未找到{},查找次数为{}次,查找过程中比较的数据为:{}'.format(
k[x], i,
str(ls)[1:-1]))
else:
print('查找{},查找次数为{}次,查找过程中比较的数据为:{}'.format(
k[x], i,
str(ls)[1:-1])) # 找到后返回其序号i
'''
R = [3, 9, 1, 5, 8, 10, 6, 7, 2, 4]
k = 6
print(SeqSearch1(R, k))
print(SeqSearch2(R, k))
'''
if __name__ == '__main__':
R = [
1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 17, 18, 19, 20, 24, 25, 26, 30,
35, 40, 45, 50, 100
]
K = [2, 8, 20, 30, 50, 5, 15, 33, 110]
SeqSearch1(R, K)
print()
SeqSearch2(R, K)
print()
R = [
2, 3, 5, 7, 8, 10, 12, 15, 18, 20, 22, 25, 30, 35, 40, 45, 50, 55, 60,
80, 100
]
K = [22, 8, 80, 3, 100, 1, 13, 120]
SeqSearch1(R, K)
print()
SeqSearch2(R, K)
十一、Sort
'''
对教材中,直接插入排序源码InsertSort.py,
冒泡排序源码BubbleSort.py,
快速排序源码QuickSort.py,
简单选择排序源码SelectSort.py,
堆排序源码HeapSort.py进行简单改写,
使它们每一趟排序完成之后,输出该趟排序的结果。
注意要标出有序区域,如[1,6,9] 3, 8, 4,。深入理解不同算法的差别。
'''
def show(r):
temp = ["["]
f = 1
for i in range(1, len(r)):
if r[i] < r[i - 1] and f:
temp.append(str(r[i - 1]))
temp.append("]")
temp.append(",")
temp.append("[")
elif r[i] > r[i - 1]:
f = 1
temp.append(str(r[i - 1]))
temp.append(",")
else:
temp.append(str(r[i - 1]))
temp.append(",")
temp.append(str(r[-1]))
temp.append("]")
return temp
def InsertSort(R):
for i in range(1, len(R)):
if R[i] < R[i - 1]:
tmp = R[i]
j = i - 1
while True:
R[j + 1] = R[j]
j -= 1
if j < 0 or R[j] <= tmp:
break
R[j + 1] = tmp
print("".join(show(R)))
return R
def BubbleSort(r):
for i in range(len(r) - 1):
exchange = 0
for j in range(len(r) - 1, i, -1):
if r[j] < r[j - 1]:
r[j], r[j - 1] = r[j - 1], r[j]
exchange = 1
print("".join(show(r)))
if not exchange:
return r
def Partition3(r, s, t):
i, j = s, s + 1
base = r[s]
while j <= t:
if r[j] <= base:
i += 1
if i != j:
r[j], r[i] = r[i], r[j]
j += 1
r[s], r[i] = r[i], r[s]
return i
def QuickSort(r):
QuickSort1(r, 0, len(r) - 1)
return r
def QuickSort1(r, s, t):
if s < t:
i = Partition3(r, s, t)
QuickSort1(r, s, i - 1)
print("".join(show(r)))
QuickSort1(r, i + 1, t)
print("".join(show(r)))
def SelectSort(r):
for i in range(len(r) - 1):
minj = i
for j in range(i + 1, len(r)):
if r[j] < r[minj]:
minj = j
if minj != i:
r[i], r[minj] = r[minj], r[i]
print("".join(show(r)))
return r
def SiftDown(low, high):
global temp
i = low
j = 2 * i + 1
tmp = temp[i]
while j <= high:
if j < high and temp[j] < temp[j + 1]:
j += 1
if tmp < temp[j]:
temp[i] = temp[j]
i, j = j, 2 * j + 1
else:
break
temp[i] = tmp
def HeapSort():
global temp
n = len(temp)
for i in range(n // 2 - 1, -1, -1):
SiftDown(i, n - 1)
print("".join(show(temp)))
for i in range(n - 1, 0, -1):
temp[0], temp[i] = temp[i], temp[0]
SiftDown(0, i - 1)
print("".join(show(temp)))
temp = [
1, 2, 3, 4, 35, 40, 17, 26, 30, 45, 25, 10, 11, 6, 7, 8, 9, 18, 19, 20, 24,
12, 13, 50, 100
]
# print("HeapSort")
# print(InsertSort(temp))
# print(BubbleSort(temp))
QuickSort(temp)
# print(SelectSort(temp))
# HeapSort()
十二、SqList
'''
题目一:设计整数顺序表的基本运算程序,并用相关数据进行测试
'''
# 线性表的顺序表
class SqList:
# 构造函数
def __init__(self) -> None:
self.initcapacity = 50000000 # 初始容量设置为50000000,方便后面进行比较
self.capacity = self.initcapacity # 容量设置为初始容量
self.data = [None] * self.capacity # 设置顺序表的空间
self.size = 0 # 长度设置为0
# 改变顺序表的容量为newcapacity
def resize(self, newcapacity):
olddata = self.data
self.data = [None] * newcapacity
self.capacity = newcapacity
for i in range(newcapacity):
self.data[i] = olddata[i]
# 由数组a中元素整体建立顺序表
def CreateList(self, a):
for i in range(len(a)):
if self.capacity == self.size: # 满时倍增容量
self.resize(2 * self.capacity)
self.data[self.size] = a[i]
self.size += 1 # 添加后元素个数增加1
# 在线性表的末尾添加一个元素e
def Add(self, e):
if self.capacity == self.size: # 满时倍增容量
self.resize(2 * self.capacity)
self.data[self.size] = e #添加元素e
self.size += 1 # 添加后元素个数增加1
# 返回长度
def getsize(self):
return self.size
# 求序号为i的元素
def __getitem__(self, i):
return self.data[i]
# 设置序号为i的元素
def __setitem__(self, i, x):
self.data[i] = x
# 查找第一个为e的元素的序号
def GetNo(self, e):
i = 0
while i < self.size and self.data[i] != e:
i += 1
if i >= self.size:
return -1
return i
# 在线性表中序号i位置插入元素e
def Insert(self, i, e):
if self.capacity == self.size: # 满时倍增容量
self.resize(2 * self.capacity)
for j in range(self.size, i, -1): # 将data[i]及后面元素后移一个位置
self.data[j] = self.data[j - 1]
self.data[i] = e # 插入元素e
self.size += 1 # 长度增1
def Delete(self, i):
for j in range(i, self.size - 1):
self.data[j] = self.data[j + 1] # 将data[i]之后的元素前移一个位置
self.size -= 1 # 长度减1
if self.capacity > self.initcapacity and self.size <= self.capacity / 4:
self.resize(self.capacity // 2) # 满足要求容量减半
# 输出顺序表
def display(self):
for i in range(self.size):
print(self.data[i], end=' ')
print()
# 测试数据
if __name__ == '__main__':
L = SqList()
for i in range(1, 6):
L.Add(i)
print("L: ", end='')
L.display()
f = L.GetNo(3)
print("第一个为3的元素的序号为%d" % (L[f]))
print("序号为2的元素=%d" % (L[2]))
print("设置序号为2的元素为8")
L[2] = 8
print("序号为2的元素=%d" % (L[2]))
n = L.getsize()
print("size=%d" % (n))
for i in range(0, n):
print("删除%d序号的元素" % (0))
L.Delete(0)
print("L: ", end='')
L.display()
print("size=%d" % (L.getsize()))
十三、Tup
'''1.根据教材源码Tup.py,根据稀疏矩阵的三元组表示方法,将类TupClass补充完整,使其支持以下基本运算:
(1) CreateTup(self,a, m.n):# 由m行n列的稀疏短阵A创建其三元组表示。
(2) Setvalue(self,i,j, x):# 利用三元组给稀疏矩阵的元素赋值,即执行A[i,j]=x(为非零值)。
(3) Getvalue(self,1j):# 利用三元组取稀疏矩阵的元素值即执行x=A[i,j]]。
(4) DispTup(self):# 输出稀疏矩阵的三元组表示。'''
class TupElem: # 三元组元素类
def __init__(self, r1, c1, d1): # 构造方法
self.r = r1 # 行号
self.c = c1 # 列号
self.d = d1 # 元素值
class TupClass: # 三元组表示类
def __init__(self, rs, cs, ns): # 构造方法
self.rows = rs # 行数
self.cols = cs # 列数
self.nums = ns # 非零元素个数(?)
self.data = [] # 稀疏矩阵对应的三元组顺序表
def CreateTup(self, A, m, n): # 由m行n列(?)的稀疏矩阵A创建其三元组表示
for i in range(m):
for j in range(n):
if A[i][j] != 0:
a = TupElem(i, j, A[i][j])
self.data.append(a)
def Setvalue(self, i, j, x): # 利用三元组给稀疏矩阵的元素赋值,即执行A[i][j]=x
f = 0
for c in range(len(self.data)):
if self.data[c].r == i and self.data[c].c == j:
self.data[c].d = x
f = 1
break
if f == 0:
for t in range(len(self.data)):
if self.data[t].r >= i and self.data[t].c >= j:
if t != 0:
self.data.insert(t - 1, TupElem(i, j, x))
else:
self.data.insert(t, TupElem(i, j, x))
break
def Getvalue(self, i, j): # 利用三元组取稀疏矩阵的元素值,即执行x=A[i][j]
for c in self.data:
if c.r == i and c.c == j:
return c.d
else:
return 0
def DisTup(self): # 输出稀疏矩阵的三元组表示
for i in self.data:
print(i.r, i.c, i.d)
print()
if __name__ == "__main__":
A = [[0, 0, 1], [4, 0, 0], [0, 5, 2]]
L = TupClass(3, 3, 4)
L.CreateTup(A, 3, 3)
L.DisTup()
L.Setvalue(0, 1, 6)
L.DisTup()
print(L.Getvalue(1, 2))
print()
L.DisTup()