'''
双指针问题
指针最大的优点是可以有效利用零碎的内存空间
本部分内容主要涉及的三个问题:
1)数组合并:合并两个有序的数组
2)二分查找:在有序数组中查找元素
3)链表:链表的概念和应用
'''
一、用指针合并两个有序数组
arr1 = [1,3,4,6,10]
arr2 = [2,5,8,11]
ind = 0
ans = arr1.copy()
for i in range(0,len(arr2)):
while(ind<len(arr1)):
if arr2[i]<=arr1[ind]:
ans.insert(i+ind,arr2[i])
break
else:
ind +=1
else: # 如果arr1已遍历完,则将剩下的arr2中的内容拼到arr1结尾
ans = ans + arr2[i:]
break
二、有序数组的二分查找
numbers = [1,3,5,6,7,8,13,14,15,17,18,24,30,43,56]
head,tail = 0,len(numbers)
search = int(input('enter a number to search:'))
#while head < tail:
while tail - head >1:
mid = (tail + head)//2
if search < numbers[mid]:
tail = mid
elif search > numbers[mid]:
head = mid
elif search == numbers[mid]:
ans = mid
break
else:
if search == numbers[head]:
ans = head
else:
ans = -1
print(ans)
三、单链表
# 输出一个由两个列表组成的单链表
print('输出一个由两个列表组成的单链表\n')
listvalue = [1,5,6,2,4,3]
listpointer = [3,2,-1,5,1,4]
head = 0
print(listvalue[head])
next = listpointer[head]
while next!=-1:
print(listvalue[next])
next = listpointer[next]
# 输出一个列表套列表组成的单链表
print('\n 输出一个列表套列表组成的单链表\n')
value = 0 # 预先设置好值和指针在小数组中的位置
pointer = 1
linkedlist = [[1,3],[5,2],[6,-1],[2,5],[4,1],[3,4]]
head = 0
print(linkedlist[head][value])
next = linkedlist[head][pointer]
while next!=-1:
print(linkedlist[next][value])
next = linkedlist[next][pointer]
四、双链表 (正序输出实例)
# 输出一个由三个列表组成的双链表
print('输出一个由三个列表组成的双链表\n')
listvalue = [1,5,6,2,7,3]
listright = [3,2,4,5,-1,1]
listleft = [-1,5,1,0,2,3]
head = listleft.index(-1) # 头指针的值为-1在listleft中的位置
print(listvalue[head])
next = listright[head]
while next!=-1:
print(listvalue[next])
next = listright[next]
# 输出一个列表套列表组成的双链表
print('\n 输出一个列表套列表组成的双链表\n')
right = 1
left = 2
value = 0
linkedlist = [[1,3,-1],[5,2,5],[6,4,1],[2,5,0],[7,-1,2],[3,1,3]]
head = 0 # 提前设置头指针指向的位置
print(linkedlist[head][value])
next = linkedlist[head][right]
while next!=-1:
print(linkedlist[next][value])
next = linkedlist[next][right]
五、双链表 (双向输出实例)
# 输出一个由三个列表组成的双链表
print('输出一个由三个列表组成的双链表\n')
listvalue = [1,5,6,2,7,3]
listright = [3,2,4,5,-1,1]
listleft = [-1,5,1,0,2,3]
head = listleft.index(-1) # 头指针的值为-1在listleft中的位置
print(listvalue[head])
next = listright[head]
while next!=-1:
print(listvalue[next])
next = listright[next]
print('从这里开始反向输出')
head = listright.index(-1) # 从这里开始反向输出
print(listvalue[head])
next = listleft[head]
while next!=-1:
print(listvalue[next])
next = listleft[next]
六、向单链表中添加元素
# 定义一个函数用于输出链表
def Output(listvalue,listright,head):
print(listvalue[head])
next = listright[head]
while next!=-1:
print(listvalue[next])
next = listright[next]
listvalue = [1,5,6,2,7,3]
listright = [3,2,4,5,-1,1]
head = 0
prepos = 5 # 已知要插入的上一个元素的位置
print('输出未插入元素的链表')
Output(listvalue,listright,head)
print()
listvalue.append(4) # 向数组末尾加上新元素的值4
listright.append(listright[prepos])
listright[prepos] = len(listvalue)-1 # 上一个元素的指针指向新元素
print('输出插入元素的链表')
Output(listvalue,listright,head)
七、向双链表中添加元素
# 定义一个函数用于输出链表
def Output(listvalue,listright,head):
print(listvalue[head])
next = listright[head]
while next!=-1:
print(listvalue[next])
next = listright[next]
listvalue = [1,5,6,2,7,3]
listright = [3,2,4,5,-1,1]
listleft = [-1,5,1,0,2,3]
head = 0
prepos = 5 # 已知要插入的上一个元素的位置
print('输出未插入元素的双链表')
Output(listvalue,listright,head)
print()
listvalue.append(4) # 向数组末尾加上新元素的值4
listright.append(listright[prepos]) # 给新元素的两个指针赋值
listleft.append(prepos)
listright[prepos] = len(listvalue)-1 # 给前后两个元素的指针指向新元素
listleft[listright[prepos]]=len(listvalue)-1
print('输出插入元素的双链表')
Output(listvalue,listright,head)
八、删除单链表中的元素
# 定义一个函数用于输出链表
def Output(listvalue,listright,head):
print(listvalue[head])
next = listright[head]
while next!=-1:
print(listvalue[next])
next = listright[next]
listvalue = [1,5,6,2,7,3]
listright = [3,2,4,5,-1,1]
head = 0
prepos = 5 # 已知要删除的上一个元素的位置
print('输出未删除元素的单链表')
Output(listvalue,listright,head)
print()
listright[prepos]=listright[listright[prepos]] # 删除元素
print('输出删除元素的单链表')
Output(listvalue,listright,head)
九、删除双链表中的元素
# 定义一个函数用于输出链表
def Output(listvalue,listright,head):
print(listvalue[head])
next = listright[head]
while next!=-1:
print(listvalue[next])
next = listright[next]
listvalue = [1,5,6,2,7,3]
listright = [3,2,4,5,-1,1]
listleft = [-1,5,1,0,2,3]
head = 0
prepos = 5 # 已知要删除的上一个元素的位置
print('输出未删除元素的双链表')
Output(listvalue,listright,head)
print()
listright[prepos] = listright[listright[prepos]] # 把前一个元素的right指针指向后一个元素
listleft[listright[listright[prepos]]]=prepos # 把后一个元素的left指针指向前一个元素
print('输出删除元素的双链表')
Output(listvalue,listright,head)
参考书籍:《你也能看得懂的Python算法书》/王硕等编著.—北京:电子工业出版社,2018.11