算作自己的一次复习
排序
冒泡排序
C语言
#include <stdbool.h>
#include <stdio.h>
#define GET_ARRAY_LEN(array, len) {len = (sizeof(array) / sizeof(array[0]));}
void bubbleSort(int a[], int count) {
int index, temp;
bool flag = true;
for (index = 1; index <= count; index++) {
for (int pos = 0; pos < count - index; pos++) {
if (a[pos] > a[pos + 1]) {
temp = a[pos];
a[pos] = a[pos + 1];
a[pos + 1] = temp;
flag = false;
}
}
if (flag) {
break;
}
}
}
void main() {
int a[] = {1, 2, 323423, 234, 43652, 234, 24, 6457, 7457, 35, 23};
int len;
GET_ARRAY_LEN(a, len);
bubbleSort(a, len);
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
}
python
#!/usr/bin/python
# -*- coding: utf-8 -*-
def bubble_sort(r_list):
flag = True
for index in range(len(r_list)-1, 0, -1):
if flag:
flag = False
for i in range(index):
if r_list[i] > r_list[i+1]:
r_list[i], r_list[i+1] = r_list[i+1], r_list[i]
flag = True
if __name__ == '__main__':
test_list = [4, 6, 9, 11, 3, 2, 0]
bubble_sort(test_list)
print test_list
插入排序
python 递归版本
def insert_sort(r_list):
r_len = len(r_list)
if r_len > 1:
r_list = insert_sort(r_list[:r_len-1]) + [r_list[-1]]
else:
return r_list
i = r_len - 1
while i > 0:
j = i - 1
if r_list[j] > r_list[i]:
r_list[i], r_list[j] = r_list[j], r_list[i]
i -= 1
return r_list
python another version
def insert_sort(r_list, r_len=None):
if r_len is None:
r_len = len(r_list)
if r_len > 1:
insert_sort(r_list, r_len-1)
else:
return
i = r_len - 1
j, temp = i, r_list[i]
while j > 0 and temp < r_list[j-1]:
r_list[j] = r_list[j-1]
j -= 1
r_list[j] = temp
堆排序
使用官方库
import heapq
data = [9, 3, 5, 7, 2, 4, 6, 8, 0]
result = []
heapq.heapify(data)
while data:
result.append(heapq.heappop(data))
return result
自己写
def heap_adjust(heap, i, h_len):
while 2 * i + 1 < h_len:
child = 2 * i + 1
if child + 1 < h_len:
if heap[child] < heap[child + 1]:
child += 1
if heap[i] < heap[child]:
heap[i], heap[child] = heap[child], heap[i]
i = child
else:
break
def heap_sort(heap):
n = len(heap)
for x in reversed(xrange(n // 2)):
heap_adjust(heap, x, n)
for y in xrange(n-1, 0, -1):
heap[0], heap[y] = heap[y], heap[0]
heap_adjust(heap, 0, y)
快速排序
def qsort(L):
if len(L) <= 1: return L
return qsort([lt for lt in L[1:] if lt < L[0]]) + [L[0]] + qsort([ge for ge in L[1:] if ge >= L[0]])
线性排序
主要有计数排序、桶排序和基数排序,均为稳定算法
查找
查找数组中的最大值和最小值
思路:
数组中的元素每两个进行一组一次比较,较大元素放到大元素表中,较小元素放到小元素表中,分组的复杂度n/2
在小元素表中逐个比较找到最小值即整个数组的最小值,复杂度n/2;在大元素表中逐个比较找到最大值,即数组的最大值,复杂度也是n/2
总的复杂度3n/2,代码如下
def find_max_and_min(r_list):
r_len = len(r_list)
if r_len < 1:
return (None,) * 2
if r_len % 2 == 0:
start = 2
max_item, min_item = r_list[0], r_list[1]
if max_item < min_item:
max_item, min_item = min_item, max_item
else:
max_item, min_item = (r_list[0],) * 2
start = 1
while start < r_len:
min_test, max_test = r_list[start], r_list[start + 1]
if min_test > max_test:
min_test, max_test = max_test, min_test
if min_test < min_item:
min_item = min_test
if max_test > max_item:
max_item = max_test
start += 2
return max_item, min_item
二分查找
使用官方库
from bisect import bisect_left
def binary_search(a, x, low=0, high=None):
high = high if high is not None else len(a) # hi defaults to len(a)
pos = bisect_left(a, x, low, high)
return (pos if pos != high and a[pos] == x else -1)
自己写
def binary_search(r_list, target):
low, high = 0, len(r_list)
while low <= high:
mid = (low + high) // 2
if r_list[mid] == target:
return mid
elif r_list[mid] > target:
high = mid - 1
else:
low = mid + 1
return -1
用递归写
def binary_search(r_list, target, low=0, high=None):
if high is None:
high = len(r_list)
if low <= high:
mid = (low + high) // 2
mid_val = r_list[mid]
if mid_val == target:
return mid
elif mid_val > target:
return binary_search(r_list, target, low, mid-1)
else:
return binary_search(r_list, target, low+1, high)
else:
return -1
链表
反转单链表
主要设置好变量,这个不难,所以一般会要求写得快又准
class Node(object):
def __init__(self, data=None):
self.data = data
self.next = None
def reverse(r):
if r.next is None:
return r
head = r
cur = r.next
tail = r # new linked node tail, will return as new head
while cur:
tmp = cur.next
head.next = tmp
cur.next = tail
tail = cur
cur = tmp
return tail
def print_node(x):
link_list = []
while x:
link_list.append(x.data)
x = x.next
print ' -> '.join(map(str, link_list))
def main():
a = Node(1)
a.next = Node(2)
a.next.next = Node(3)
print_node(a)
print
b = reverse(a)
print_node(b)
if __name__ == '__main__':
main()
字符串
最长公共子串
代码来自英文维基,原理是构造矩阵,找最长的对角线连续不为0的长度
def longest_common_substring(s1, s2):
m = [[0] * (1 + len(s2)) for i in xrange(1 + len(s1))]
longest, x_longest = 0, 0
for x in xrange(1, 1 + len(s1)):
for y in xrange(1, 1 + len(s2)):
if s1[x - 1] == s2[y - 1]:
m[x][y] = m[x - 1][y - 1] + 1
if m[x][y] > longest:
longest = m[x][y]
x_longest = x
else:
m[x][y] = 0
return s1[x_longest - longest: x_longest]
最长公共子序列
不要求字符是连续的,下面解法有最大递归1000的限制,所以还是使用自顶向上的DP更好一点,有兴趣可以看这里
def memoize(fn):
cache = dict()
def wrapped(*v):
key = tuple(v) # tuples are hashable, and can be used as dict keys
if key not in cache:
cache[key] = fn(*v)
return cache[key]
return wrapped
def lcs(xs, ys):
@memoize
def lcs_(i, j):
if i and j:
xe, ye = xs[i-1], ys[j-1]
if xe == ye:
return lcs_(i-1, j-1) + [xe]
else:
return max(lcs_(i, j-1), lcs_(i-1, j), key=len)
else:
return []
return lcs_(len(xs), len(ys))
最大子序列
待续
排列与组合
组合
通常的实现是10置换法
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
排列
其实就是将组合得到的每个分组进行全排列
def permutations(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = range(n)
cycles = range(n, n-r, -1)
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
这两段代码里都用到了for...else
的语句结构,return
放不放在else
下的区别是,当for循环里break
时,可以跳过return
,否则必须经过return
。当经过完所有for
的条件后,将会返回
这两段代码的结果都是字典序由小到大
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。