数据结构与算法(入门笔记)

数据结构与算法(入门笔记)

数据结构与算法

算法是一种解决问题的思想和方法

五大特性:

1:输入:0个或多个输入。

2:输出:1个或多个输出。

3:有穷性:一定的步骤和时间内完成

4:可行性:每一步都可以执行

5:确定性:每一步不能产生歧义

时间复杂度

T(n) = O(n^x)

最优时间复杂度:算法完成工作最少需要的基本操作

最坏时间复杂度:算法完成工作最多需要的基本操作

平均时间复杂度:算法完成工作平均需要的基本操作

时间复杂度的基本计算规则

1、基本操作:只有常数项,认为其时间复杂度为O(1)

2、顺序结构:加法

3、循环结构:乘法

4、分支结构:取最大值

5、判断一个算法的效率时,一般只考虑操作数量的最高次项,其他次要项可以忽略

6、没有特殊说明时,时间复杂度一般是指最坏时间复杂度

空间复杂度S(n)

空间复杂度是指一个算法运行时所占用存储空间的大小量度

顺序表

顺序表:将元素顺序地存放在一块连续的存储区里,元素间的顺序关系 由它们的存储顺序自然表示。

扩充的两种策略

线性扩充:每次扩充增加固定数目的存储位置,如每次扩充增加10个元素位置,这 种策略可称为线性增长。

特点:节省空间,但是扩充操作频繁,操作次数多。

加倍扩充:每次扩充容量加倍,如每次扩充增加一倍存储空间。

特点:减少了扩充操作的执行次数,但可能会浪费空间资源。以空间换时间,推荐的方式。

list的基本实现技术

list就是一种采用分离式技术实现的动态顺序表

链表

链表:将元素存放在通过链接构造起来的一系列存储块中。

单向链表

单向链表:一个信息域(元素域)和一个链接域。信息域记录本身元素信息,链接域指向下一个链表的信息域。

单向链表的操作:

is_empty() #判断链表是否为空
length() #返回链表的长度
travel() #遍历
add(item) #在头部添加一个节点
append(item) #在尾部添加一个节点
insert(pos, item) #在指定位置pos添加节点
remove(item) #删除一个节点
search(item) #查找节点是否存在

双向链表

双向链表:每个节点有两个链接:一个指 向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个 节点,当此节点为最后一个节点时,指向空值。

双向链表的操作:

is_empty() #判断链表是否为空
length() #返回链表的长度
travel() #遍历
add(item) #在头部添加一个节点
append(item) #在尾部添加一个节点
insert(pos, item) #在指定位置pos添加节点
remove(item) #删除一个节点
search(item) #查找节点是否存在

单向循环链表

单向循环链表:链表中最后一个节点的next域不再为 None,而是指向链表的头节点。

循环链表的操作:

is_empty() #判断链表是否为空
length() #返回链表的长度
travel() #遍历
add(item) #在头部添加一个节点
append(item) #在尾部添加一个节点
insert(pos, item) #在指定位置pos添加节点
remove(item) #删除一个节点
search(item) #查找节点是否存在

栈(stack)

栈(stack),有些地也称为堆栈,是⼀种容器,可存储数据元素、访问元 素、删除元素,它的特点在于只能允许在容器的一端(称为栈顶端指标,英 语:top)进行加减数据(英语:push)和输出数据(英语:pop)的运算。

栈的操作

Stack() #创建一个新的空栈

push(item) #添加一个新的元素item到栈顶 

pop() #弹出栈顶元素 

peek() #返回栈顶元素 

is_empty() #判断栈是否为空 

size() #返回栈的元素个数 

队列

队列(queue)是只允许在一端进行插入操作,在另一端进行删除操作的 线性表。

队列是一种先进先出的(First In First Out)的线性表,简称FIFO

队列的操作

Queue() #创建一个空的队列
enqueue(item) #往队列中添加一个item元素
dequeue() #从队列头部删除一个元素
is_empty() #判断一个队列是否为空
size() #返回队列的大小

排序与搜索

稳定性

稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表 中R出现在S之前,在排序过的列表中R也将会是在S之前 

冒泡排序

冒泡排序原理

  • 相邻替换:相邻的元素进行替换
  • 比较循环:重复相邻替换
  • 冒泡循环:循环n-1次,最后一个元素不需要进行比较

冒泡排序(稳定)

# 降序
def bubble_sort(alist):
    n = len(alist)
    for j in range(n-1):   #重复交换的次数
        # j=[0,1,2···n-1]
        for i in range(0,n-1-j): #进行位置交换
            if alist[i] > alist[i+1]:
                alist[i],alist[i+1] = alist[i+1],alist[i]

选择排序(不稳定)

# 升序
def select_sort(alist):
    n = len(alist)
    for i in range(n-1):   # 确定最小值该在的位置
        min_index = i
        for j in range(i+1,n):   # 确定剩下数组最小值的索引
            if alist[j] < alist[min_index]:
                min_index = j
        if min_index != i:  # 若最小值不在最小索引处,交换位置
            alist[i],alist[min_index] = alist[min_index],alist[i]

插入排序(稳定)

def insert_sort(alist):
    '''插入排序'''
    n = len(alist)
    for i in range(1,n):
        for j in range(i,1,-1):
            if alist[j] < alist[j-1]:
                alist[j-1],alist[j] = alist[j],alist[j-1]
            else:
                break

希尔排序(不稳定)

def shell_sort(alist):
    n = len(alist)
    # 初始步长
    gap = n // 2
    while gap > 0:
        for i in range(gap,n):
            j = i
            while j >= gap and alist[j-gap] > alist[j]:
                alist[j-gap],alist[j] = alist[j],alist[j-gap]
                j -= gap
        gap = gap//2 

快速排序(不稳定)

def quick_sort(alist):
    '''快速排序'''
    n = len(alist)
    if start >= end:
        return
    mid = alist[start]
    left = start
    right = end
    # left与right未重合,向中间移动
    while left < right:
        while left < right and alist[right] >= mid:
            right -= 1
        alist[left] = alist[right]
        while left < right and alist[left]< mid:
            left += 1
        alist[right] = alist[left]
    # 从循环退出后,left与right相遇,即left=right   
    alist[left] = mid
    # 对左边部分进行快速排序
    quick_sort(alist,start,left-1)
    # 对右边进行快速排序
    quick_sort(alist,left+1,end)

归并排序(稳定)

n个元素
二分法分割m次后的元素数n/2^m=1,m=logn
合并操作,执行n次
def merge_sort(alist):
    n = len(alist)
    if 1 == n :
        return alist
    mid = n//2
    left_sorted_li = merge_sort(alist[:mid])
    right_sorted_li = merge_sort(alist[mid:])
    left,right = 0,0
    merge_sorted_li = []
    left_n = len(left_sorted_li)
    right_n = len(right_sorted_li)

    while left < left_n and right < right_n:
        if left_sorted_li[left] <= right_sorted_li[right]:
            merge_sorted_li.append(left_sorted_li[left])
            left += 1
        else:
            merge_sorted_li.append(right_sorted_li[right])
            right += 1
    merge_sorted_li += left_sorted_li[left:]
    merge_sorted_li += right_sorted_li[right:]
    return merge_sorted_li

二叉树

class Node(object):
    def __init__(self,item):
        self.item = item
        self.lchild = None
        self.rchild = None

class BinaryTree(object):
    '''二叉树'''
    def __init__(self,node=None):
        selt.root = node
    def add(self,item):
        if self.root is None:
            self.root = Node(item)
        else:
            queue = []
            queue.append(self.root)

            while len(queue) > 0:
                node = queue.pop(0)
                if not node.lchild:
                    node.lchild = Node(item)
                    return
                else:
                    queue.append(node.lchild)
                if not node.rchild:
                    node.rchild = Node(item)
                    return
                else:
                    queue.append(node.rchild)
   def bread_travel(self):
        '''广度优先遍历'''
        if self.root is None:
            return
        queue = []
        queue.append(self.root)
        while len(queue)>0:
            node = queue.pop(0)
            if node.lchild:
            queue.append(node.lchild)
            if not rchild:
                queue.append(node.rchild)
    def preorder_travel(self,root):
        '''先序遍历'''
        if root:
        self.preorder_travel(root.lchild)
        self.preorder_travel(root.rchild)
    def inorder_travel(self,root):
        '''中序遍历'''
        if root:
        self.inorder_travel(root.lchild)
        self.inorder_travel(root.rchild)
    def postorder_travel(self,root):
        '''后序遍历'''
        if root:
        self.postorder_travel(root.lchild)
        self.postorder_travel(root.rchild)

猜你喜欢

转载自blog.csdn.net/weixin_42799711/article/details/81636118
今日推荐