数据结构与算法

56 阅读4分钟

什么是数据结构

数据结构是计算机中存储、组织数据的方式,精心选择的数据结构可以带来最优效率的算法。

为什么要学习数据结构和算法?

随着应用程序变得越来越复杂和数据越来越丰富,几百万、几十亿甚至几百亿的数据就会出现,而对这么大对数据进行搜索、插入或者排序等的操作就越来越慢,数据结构就是用来解决这些问题的。

常见的数据结构

  • 栈(Stack):栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操作。
  • 队列(Queue):队列和栈类似,也是一种特殊的线性表。和栈不同的是,队列只允许在表的一端进行插入操作,而在另一端进行删除操作。
  • 数组(Array):数组是一种聚合数据类型,它是将具有相同类型的若干变量有序地组织在一起的集合。
  • 链表(Linked List):链表是一种数据元素按照链式存储结构进行存储的数据结构,这种存储结构具有在物理上存在非连续的特点。
  • 树(Tree):树是典型的非线性结构,它是包括,2 个结点的有穷集合 K。
  • 图(Graph):图是另一种非线性数据结构。在图结构中,数据结点一般称为顶点,而边是顶点的有序偶对。
  • 堆(Heap):堆是一种特殊的树形数据结构,一般讨论的堆都是二叉堆。
  • 散列表(Hash table):散列表源自于散列函数(Hash function),其思想是如果在结构中存在关键字和T相等的记录,那么必定在F(T)的存储位置可以找到该记录,这样就可以不用进行比较操作而直接取得所查记录。

常用算法

数据结构研究的内容:就是如何按一定的逻辑结构,把数据组织起来,并选择适当的存储表示方法把逻辑结构组织好的数据存储到计算机的存储器里。算法研究的目的是为了更有效的处理数据,提高数据运算效率。数据的运算是定义在数据的逻辑结构上,但运算的具体实现要在存储结构上进行。一般有以下几种常用运算:

  • 检索:检索就是在数据结构里查找满足一定条件的节点。一般是给定一个某字段的值,找具有该字段值的节点。
  • 插入:往数据结构中增加新的节点。
  • 删除:把指定的结点从数据结构中去掉。
  • 更新:改变指定节点的一个或多个字段的值。
  • 排序:把节点按某种指定的顺序重新排列。例如递增或递减。

1.0 栈结构

特点:后进先出 Last in Out first(LIOF)

zhan.png 解释: 上图的四个数据,假设我想拿到数据a2 必须先把数据a4拿出来,然后拿a3,然后才能取到a2 这个数据。 栈结构只有一个出入口。

1.1 封装栈结构

    /*
    * push 添加一个元素到栈顶
    * pop 出栈
    * peek 返回栈顶
    * isEmpty 判断是不是空
    * clear 清楚栈
    * size 返回栈的长度
    * toString 转为字符串
    * */
    class Stack{
        item = [];
        push(data){
            this.item.push(data)
        }
        pop(){
           return this.item.pop()
        }
        peek(){
            return this.item.at(-1)
        }
        isEmpty(){
            return this.item.length === 0
        }
        clear(){
            this.item = []
        }
        size(){
            return this.item.length
        }
        toString(){
            return this.item.join('-')
        }
    }
    let stack = new Stack()
    stack.push(1)
    stack.push(2)
    stack.push(3)
    console.log(stack.item) //[1,2,3]
    console.log(stack.peek()) // 3
    console.log(stack.toString()) // 1-2-3
    let out = stack.pop()
    console.log(out,stack.item) // 3 [1,2]

1.2 栈结构的应用

知识前瞻,比如10进制转2进制

比如 50 转为2进制应该是什么样子的

10进制转为2进制求余数
50%20
25%21
12%20
6%20
3%21
1%21

所以结果为 110010

练习10进制转为2进制

function convent(decNumber){
    let remStack = new Stack()
    let number = decNumber
    let str = ''

    while(number > 0){ // 大于0就一直循环
        remStack.push(number % 2)
        number = Math.floor(number / 2) // 向下取整
    }
    while(!(remStack.isEmpty())){ // 不是空的累加值
        str += remStack.pop()
    }
    return str
}
console.log(convent(50)) // 110010

升级版 10进制转为任意进制,目前计算常用的进制是 2,8 ,10,16进制

    function convent(decNumber,base){
        let remStack = new Stack()
        let number = decNumber
        let str = '';
        let baseStr = "0123456789ABCDEF" // 16进制表示法

        while(number>0){ // 除以2不等于0就一直循环
            remStack.push(number % base)
            number = Math.floor(number / base) // 向下取整
        }
        while(!(remStack.isEmpty())){ // 不是空的累加值
            str += baseStr[remStack.pop()]
        }
        return str
    }
  convent(500,16) // 1F4

请让我独自行事,自由做梦,任凭明天对我裁决。

qdysh.png