【python】数据结构与算法简介及单链表实现

数据结构和算法

简介:

​ 数据结构是存储和组织数据的一种方式,算法是位实现业务目的的各种方法和思路,作用是大大提升程序性能

1.算法的特性:

​ 1.独立性: 算法是独立存在的一种解决问题的方法和思想对于算法而言;实现的语言并不重要,重要的是思想;算法可以有不同的语言描述实现版本(如C描述、C++描述、Python描述等)

​ 2.算法的五大特性:
​ ①有输入
​ 算法具有0个或多个输入
​ ②有输出
算法至少有1个或多个输出
​ ③有穷性
算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
​ ④确定性
算法中的每一步都有确定的含义,不会出现二义性
​ ⑤可行性
算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成

时间复杂度介绍:

概述:

​ 它可以反应一个算法的优略,表示一个算法随着问题规模变化而表现出来的趋势

大O标记法:

​ 忽略次要条件,只考虑主要条件,就会得到时间和n(问题规模)的关系用O(n)表示

时间复杂度的的计算:

①基本操作
​ 时间复杂度为O(1)
②顺序结构
​ 时间复杂度按加法进行计算
③循环结构
​ 时间复杂度按乘法进行计算
④分支结构
​ 时间复杂度取最大值
⑤判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
⑥在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
所消耗的时间从小到大,常见的时间复杂度关系有:

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3)

空间复杂度从小到大

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3)

2.数据结构的概念:

​ 数据结构是存储、组织数据的方式 ,指相互之间存在一种或多种特定关系的数据元素的集合
​ 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 , 数据结构往往影响着算法的效率,相同的数据采用不同的方式也就不同的数据结构存储,带来的运行或者存储效率是不同的

数据结构羽算法的关系

​ 数据结构只是静态的描述了数据元素之间的关系,是存储和组织数据的方式。
高效的程序需要在数据结构的基础上设计和选择算法

​ 算法是为了解决实际问题而设计的,数据结构是算法需要处理问题的载体

​ 最常用的数据运算有五种:
插入,删除,修改,查找,排序等

内存中的储存结构

​ 内存是以字节为基本存储单位的, 每个基本存储空间都有自己的地址(注意:一个内存地址代表一个字节(8bit)的存储空间)。

如:

​ 整形(int) : 4个字节
​ 字符(char): 1个字节 . 单个字符“a”占1个字节, 字符串“abc”占3个字节

数据结构的类型

一.线性结构

​ 特点:每个节点都可以有多个子节点(后继节点)和 多个父节点(前驱节点)

​ 代表: 栈,队列,链表…

​ 分类:

​ 顺序表: 将元素顺序的放在一块连续的存储区域里面,元素间的关系有他们的存储顺序自然表示

​ 分为:

​ 一体式存储

在这里插入图片描述

​ 分离式结构

在这里插入图片描述

​ 链表: 将元素存放在通过链接构造起来的一系列存储块中,存储区是非连续的

2.顺序表介绍:

​ 他属于线性结构的一种,栈,队列,都属于顺序表,特点是所有元素在内存中以连续的方式来存储

顺序表的存储结构

顺序表的完整信息包括两部分:
①数据区
②信息区,即元素存储区的容量和当前表中已有的元素个数
(大白话:信息区对数据进行描述、信息显示)

​ 数据区和信息区在一起的叫一体式存储,分 开的叫分离式存储

在这里插入图片描述

顺序表的扩充策略
  • 每次扩充固定数目的位置 (时间换空间的策略)
  • 每次扩充容量加倍 (空间换时间的策略)

在这里插入图片描述

a. 尾端加入元素,时间复杂度为O(1)
b. 非保序的加入元素(不常见),时间复杂度为O(1) eg:在指定位置1号位置加入111元素
c. 保序的元素加入,时间复杂度为O(n)

在这里插入图片描述

a. 删除表尾元素,时间复杂度为O(1)
b. 非保序的元素删除(不常见),时间复杂度为O(1),比如:在指定位置删除(1号位置)删除111,153填进来
c. 保序的元素删除,时间复杂度为O(n)

3.链表介绍

​ 他是有节点组成的,每个节点又有 数值域 和 地址域来组成

​ 特点是所有元素在内存中以 非连续的内存空间来存储,即: 有地方就行

​ 链表根据节点不同,主要分为:

1.单向链表 2.单向循环链表 3.双向链表 4.双向循环链表

单链表代码演示:
'''
链表介绍
    属于线性结构,每个节点都有一个父节点和子节点,
    链表可以看作是把节点链接起来的一个链
    由元素域 和 地址域组成
单链表: 每个节点由一个数值域和地址域组成,且每一个节点的地址域指向下一个节点的地址
且最后一个节点的地址域为:None

单向循环链表:每个节点由一个数值域和地址域组成,且每一个节点的地址域指向下一个节点的地址
且最后一个节点的地址域为:第一个节点的地址

双向链表: 每个节点由1个数值域和2个地址域组成,且每个节点的地址域分别指向前后两个节点
前一个节点的前地址域为:None 最后一个节点的后地址域为:None

双向循环链表: 每个节点由1个数值域和2个地址域组成,且每个节点的地址域分别指向前后两个节点
前一个节点的前地址域为:最后一个节点 最后一个节点的后地址域为:第一个节点
'''
'''
is_empty(self) 链表是否为空
length(self) 链表长度
travel(self. ) 遍历整个链表
add(self, item) 链表头部添加元素
append(self, item) 链表尾部添加元素
insert(self, pos, item) 指定位置添加元素
remove(self, item) 删除节点
search(self, item) 查找节点是否存在
'''


# 链表节点
class Mynode:
    def __init__(self, item):
        self.item = item
        self.next = None


# 单链表
class SingleLinkedList:
    def __init__(self, head=None):
        self.head = head

    def add(self, item):
        '''
        链表头添加节点
        :param item:
        :return:
        '''
        mynode = Mynode(item)
        mynode.next = self.head
        self.head = mynode

    def append(self, item):
        '''
        链表尾添加节点
        :return:
        '''
        if self.is_empty():
            mynode = Mynode(item)
            mynode.next = self.head
            self.head = mynode
            print('添加成功')
            return True
        head = self.head
        while head:
            item1 = head
            head = head.next
        head = item1
        mynode = Mynode(item)

        head.next = mynode
        print('添加成功')
        return True
    def is_empty(self):
        '''
        判断链表是否为空
        :return:
        '''
        return self.head is None

    def length(self):
        '''
        返回列表长度
        :return:
        '''
        length = 0
        head = self.head
        while head:
            head = head.next
            length += 1
        return length

    def remove(self, item):
        '''
        删除第一个值为item的节点
        :param item:
        :return:
        '''
        if not self.search(item):
            print(f'删除失败')
            return False
        if self.head.item == item:
            self.head = self.head.next
            print(f'删除该节点成功')
            return True
        head = self.head
        last = self.head
        while head:
            if head.item == item:
                last.next = head.next
                print(f'删除该节点成功')
                return True
            last = head
            head = head.next

    def search(self, item):
        head = self.head
        count = 1
        while head:
            if head.item == item:
                print(f'在第{count}节点找到{item}')
                return True
            head = head.next
        print(f'未找到节点{item}')
        return False

    def insert(self, pos, item):
        '''
        指定位置插入节点
        :param pos:
        :param item:
        :return:
        '''
        if pos == 0:
            # 头部添加
            self.add(item)
            print('添加成功')
            return True
        pos -= 1
        if pos > self.length():
            print('插入失败,超长')
            return False

        count = 0
        head = self.head
        while count < pos:
            head = head.next
            count += 1
        mynode = Mynode(item)
        mynode.next = head.next
        head.next = mynode
        print('插入成功')
        return True

    def travel(self):
        '''
        遍历链表输出每个节点
        :return:
        '''
        count = 0
        head = self.head
        while head:
            count += 1
            print(f'第{count}个节点,值: {head.item}')
            head = head.next


if __name__ == '__main__':
    sll = SingleLinkedList()
    print(sll.is_empty())
    sll.append(123)
    sll.add('abc')
    sll.add('abc')
    sll.add('abc')
    sll.append(0)
    print(sll.is_empty())
    print(sll.length())
    sll.travel()
    sll.insert(0, 456)
    sll.travel()
    sll.search('abc')
    sll.search('12344')
    sll.remove('1233')
    sll.remove('abc')
    sll.travel()
    sll.remove(456)
    sll.travel()
    sll.add(456)
    sll.search(456)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值