学习数据结构笔记

0812

一、栈

① 先进后出(FILO),只能在一端入栈 和 出栈

② 栈的方法有:

------push()入栈 ,

------ pop()出栈 ,

------ peek()查看栈顶元素 ,

------ isEmpty() 判断是否为空 ,

------size() 栈的长度

③ 封装一个栈:

class Stack {
    constructor() {
        // 栈中的属性
        this.items = []
    }
    // 栈相关的方法
    // 压栈操作
    push(element) {
        this.items.push(element)
    }

    // 出栈操作
    pop() {
        return this.items.pop()
    }

    // peek操作
    peek() {
        return this.items[this.items.length - 1]
    }

    // 判断栈中的元素是否为空
    isEmpty() {
        return this.items.length == 0
    }

    // 获取栈中元素的个数
    size() {
        return this.items.length
    }
}

二、队列

① 先进先出(FIFO), 固定在一端进队,另一端出队

② 队列的方法:

------enqueue()入队 ,

------dequeue 出队  ,

------front()查看队首元素  ,

------ isEmpty()判空 ,

------size()队列长度

③ 封装一个队列:

class Queue{
    constructor(){
        this.item = []
    }
    enqueue(ele){
        this.item.push(ele)
    }
    dequeue(){
        return this.item.shift()
    }
    front(){
        return this.item[0]
    }
    isEmpty(){
        return this.item.length == 0
    }
    size(){
        return this.item.length
    }
}

④ 优先级队列:
 

三、链表

1、单向链表

① 链表结构:

------head 指向链表头结点

------length 链表长度

② 链表中节点结构:

------data 存放数据

------next 存放下一节点 地址

③ 链表方法:

------append(ele) 创建新节点 ;

------ insert(position,ele) 插入新节点 ;

------ removeAt(position)移除指定的项  ;

------indexOf(ele)查找目标元素下标 ;

------ remove(ele)从列表中移除一项  ;

------toString() 转成字符串   ;

------isEmpty()判空 。

④ 封装一个链表:

  // 节点结构 
        class Lnode {
            constructor(data) {
                this.data = data
                this.next = null
            }
        }
        class LinkList {
            constructor() {
                this.head = null
                this.length = 0
            }
            // 在链表尾部 新增节点
            append(data) {
                let newNode = new Lnode(data)
                // 链表为空时 直接将新节点设为 头结点
                if (this.head == null) {
                    this.head = newNode
                } 
                // 链表不为空时
                else {
                    // 找到最后一个节点
                    let current = this.head
                    while (current.next !== null) {
                        current = current.next
                    }
                    // 让最后一个节点指向 新节点
                    current.next = newNode
                }
                this.length++
            }
            // 在指定位置 新增节点
            insert(position, data) {
                if (position < 0 || position > this.length || !Number.isInteger(position)) {
                    return false
                }
                let newNode = new Lnode(data)
                if (position == 0) {//在首部添加新节点
                    newNode.next = this.head
                    this.head = newNode
                    this.length++
                } else if (position == this.length) {
                    this.append(data)
                } else {
                    let current = this.head, index = 0
                    while (index < position - 1) {
                        current = current.next
                        index++
                    }
                    newNode.next = current.next.next
                    current.next = newNode
                    this.length++
                }
            }
            removeAt(position) {
                if (position < 0 || position > this.length || !Number.isInteger(position)) {
                    return false
                }
                if (position == 0) {
                    this.head = this.head.next
                } else {
                    let current = this.head, index = 0
                    while (index < position - 1) {
                        current = current.next
                        index++
                    }
                    current.next = current.next.next
                }
                this.length--
            }
            indexOf(data) {
                let current = this.head, index = 0

                // console.log(this.length);
                while (index < this.length) {
                    if (current.data == data) {
                        return index
                    } else {
                        current = current.next
                        index++
                    }
                }
                return -1
            }
            remove(data) {
                this.removeAt(this.indexOf(data))
            }
            isEmpty() {
                return this.length == 0
            }
            toString() {
                let current = this.head, index = 0, str = ""
                while (index < this.length) {
                    str += "-" + current.data
                    current = current.next
                    index++
                }
                return str.slice(1)
            }
        }

2、双向链表

① 链表结构:

------head 指向 链表头结点 ;

------tail  指向链表 尾结点 ;

------length 链表长度 。

② 链表的节点结构:

------prev 存放上一节点 地址  ;

------next 存放下一节点 地址 ;

------data 存放数据 。

③ 链表方法:

------append(data)在链表尾部 新增新节点  ;

------insert(position ,data)在指定位置 新增新节点;

(在链表中间新增时 ,现将新节点连接上去 ,再连接 前后节点)

------removeAt (position) 删除指定位置元素

------indexOf(data) 查找data在链表中的 位置

------remove(data)删除data元素

------isEmpty()判空 ;

------forwardString() 正向转字符串

------reverseString() 逆向转字符串

④ 封装一个 双向链表:

     class DoublyLnode {
            constructor(data) {
                this.data = data
                this.prev = null
                this.next = null
            }
        }
        class DoublyLinkedList {
            constructor() {
                this.head = null
                this.tail = null
                this.length = 0
            }
            // 在链表尾部 新增一个节点
            append(data) {
                let newNode = new DoublyLnode(data)

                if (this.length == 0) {
                    this.head = newNode
                    this.tail = newNode
                } else {
                    this.tail.next = newNode
                    newNode.prev = this.tail
                    this.tail = newNode
                }
                this.length++
            }
            // 在指定位置 新增节点
            insert(position, data) {
                if (position < 0 || position > this.length || !Number.isInteger(position)) {
                    return false
                }
                let newNode = new DoublyLnode(data)

                if (position == 0) {
                    this.head.prev = newNode
                    newNode.next = this.head
                    this.head = newNode
                    this.length++
                } else if (position == this.length) {
                    this.append(data)
                } else {
                    let current = this.head, index = 0;
                    while (index < position - 1) {
                        current = current.next
                        index++
                    }
                    newNode.next = current.next
                    newNode.prev = current

                    current.next.prev = newNode
                    current.next = newNode
                    this.length++
                }
            }
            // 删除指定位置 元素
            removeAt(position) {
                if (position < 0 || position > this.length || !Number.isInteger(position)) {
                    return false
                }

                if (position == 0) {
                    this.head.next.prev = null
                    this.head = this.head.next
                } else if (position == this.length - 1) {
                    this.tail.prev.next = null
                    this.tail = this.tail.prev
                } else {
                    let current = this.head, index = 0;
                    while (index < position - 1) {
                        current = current.next
                        index++
                    }

                    current.next = current.next.next
                    current.next.prev = current
                }
                this.length--
            }

            indexOf(data) {
                let current = this.head, index = 0
                while (index < this.length) {

                    if (current.data == data) {
                        return index
                    } else {
                        current = current.next
                        index++
                    }
                }
                return -1
            }
            remove(data) {
                this.removeAt(this.indexOf(data))
            }
            isEmpty() {
                return this.length == 0
            }
            forwardString() {
                let current = this.head, index = 0, str = ""
                while (index < this.length) {
                    str += "-" + current.data
                    current = current.next
                    index++
                }
                return str.slice(1)
            }
            reverseString() {
                let current = this.tail, index = this.length - 1, str = ""
                while (index >= 0) {
                    str += "-" + current.data
                    current = current.prev
                    index--
                }
                return str.slice(1)
            }
        }

3、单向循环链表

① 链表结构 ,链表节点结构,方法同 单向链表

② 封装一个单向循环链表:
 

 class CLnode {
            constructor(data) {
                this.data = data
                this.next = null
            }
        }
        class CycleLinkList {
            constructor() {
                this.head = null
                this.length = 0
            }
            // 在链表尾部 新增节点
            append(data) {
                let newNode = new CLnode(data)
                if (this.length == 0) {
                    this.head = newNode
                    newNode.next = this.head
                } else {
                    let current = this.head
                    while (current.next != this.head) {
                        current = current.next
                    }
                    current.next = newNode
                    newNode.next = this.head
                }
                this.length++
            }
            // 在指定位置 新增节点
            insert(position, data) {
                if (position < 0 || position > this.length || !Number.isInteger(position)) return false;
                let newNode = new CLnode(data)
                if (position == 0) {
                    if (this.length == 0) {
                        this.head = newNode
                        newNode.next = this.head
                    } else {
                        let current = this.head
                        while (current.next != this.head) {
                            current = current.next
                        }
                        current.next = newNode
                        newNode.next = this.head
                        this.head = newNode
                    }
                    this.length++
                } else if (position == this.length) {
                    this.append(data)
                } else {
                    let current = this.head, index = 0
                    while (index < position - 1) {
                        current = current.next
                        index++
                    }
                    newNode.next = current.next
                    current.next = newNode
                    this.length++
                }
            }
            // 删除指定位置 的元素
            removeAt(position) {
                if (position < 0 || position > this.length || !Number.isInteger(position) || this.length == 0) return false;

                if (position == 0) {
                    if (this.length == 1) {
                        this.head = null
                    } else {
                        let current = this.head
                        while (current.next != this.head) {
                            current = current.next
                        }
                        this.head = this.head.next
                        current.next = this.head
                    }
                } else {
                    let current = this.head, index = 0
                    // 将 current移动到 目标节点的前一个位置
                    while (index < position - 1) {
                        current = current.next
                        index++
                    }
                    current.next = current.next.next
                    // 当current为最后一个节点时 , current.next.next == this.head
                }
                this.length--
            }

            indexOf(data) {
                let current = this.head, index = 0
                while (index < this.length) {
                    if (current.data == data) {
                        return index
                    } else {
                        current = current.next
                        index++
                    }
                }
                return -1
            }
            remove(data) {
                this.removeAt(this.indexOf(data))
            }
            isEmpty() {
                return this.length == 0
            }
            toString() {

                let current = this.head, index = 0, str = ""
                while (index < this.length) {
                    str += "-" + current.data
                    current = current.next
                    index++
                }
                return str.slice(1)
            }
        }

4、双向循环链表

① 链表结构 ,链表节点结构,方法同 双向链表

② 封装一个双向循环链表:

 class Cdnode {
            constructor(data) {
                this.prev = null
                this.data = data
                this.next = null
            }
        }
        class CycleDlist {
            constructor() {
                this.head = null
                this.tail = null
                this.length = 0
            }
            append(data) {
                // 新建一个节点
                let newNode = new Cdnode(data)
                // 标记
                let current = this.head, index = 0

                // 当为空链表时
                if (this.length == 0) {
                    // 直接将head tail 指向newNode
                    this.head = newNode
                    this.tail = newNode

                    this.head.prev = this.tail
                    this.tail.next = this.head

                } else {// 链表不为空时 在链表尾部 添加新结点
                    // 找到最后一个节点
                    while (index++ < this.length - 1) {
                        current = current.next
                    }
                    newNode.prev = current
                    newNode.next = this.head

                    current.next = newNode
                    this.head.prev = newNode

                    this.tail = newNode

                }
                this.length++
            }
            // 在指定位置 新增结点
            insert(position, data) {
                // 判断位置是否合法
                if (position < 0 || position > this.length || !Number.isInteger(position)) return false

                let current = this.head , index = 0
                let newNode = new Cdnode(data)

                if (position == 0) {//在首部新增结点
                    if (this.length == 0) {//链表为空时
                        this.head = newNode
                        this.tail = newNode

                        this.head.prev = this.tail
                        this.tail.next = this.head
                    } else { //链表不为空时
                        newNode.next = this.head
                        newNode.prev = this.tail

                        this.head.prev = newNode
                        this.tail.next = newNode

                        this.head = newNode
                    }
                    this.length++
                }else if(position == this.length){//在链表尾部 新增结点
                    this.append(data)
                }else{ //在链表中间新增结点
                    // 找到目标结点的上一个位置
                    while(index++ < position -1){
                        current = current.next
                    }
                    newNode.next = current.next
                    newNode.prev = current

                    current.next.prev = newNode
                    current.next = newNode
                    this.length++
                }
                
            }
            // 移除指定位置 的结点
            removeAt(position){
                // 判断位置是否合法
                if (position < 0 || position >= this.length || !Number.isInteger(position)||this.length == 0) return false
                
                let current = this.head ,index = 0 
                if(position == 0){ //移除首部结点
                    if(this.length == 1){ // 只有一个结点时
                        this.head = null
                        this.tail = null
                    }else{//有多个结点
                        this.head.next.prev = this.tail
                        this.tail.next = this.head.next

                        this.head = this.head.next
                    }
                }else if(position == this.length -1){ //移除尾部结点
                    // 找到尾部结点的前一个结点
                    while(index++ < position -1){
                        current = current.next
                    }
                    current.next = this.head
                    this.head.prev = current

                    this.tail = current
                }else{//移除中间结点
                    // 找到目标结点 的前一个 结点
                    while(index++ < position -1){
                        current = current.next
                    }
                    current.next = current.next.next
                    current.next.prev = current
                }
                this.length--
            }
            
            indexOf(data){
                let  current = this.head  ,index =0
                for(let i=0; i<this.length; i++){
                    if(current.data == data){
                        return index
                    }else{
                        current = current.next
                        index++
                    }
                }
                return -1
            }
            remove(data){
                this.removeAt(this.indexOf(data))
            }
            isEmpty() {
                return this.length == 0
            }
            forwardString() {
                let current = this.head, index = 0, str = ""
                while (index < this.length) {
                    str += "-" + current.data
                    current = current.next
                    index++
                }
                return str.slice(1)
            }
            reverseString() {
                let current = this.tail, index = this.length - 1, str = ""
                while (index >= 0) {
                    str += "-" + current.data
                    current = current.prev
                    index--
                }
                return str.slice(1)
            }

        }

四 、 集合

① 实质是一个对象 Set(),不能有重复值

② 集合的方法:
add() 在集合中 添加新元素    ; has(data)集合中是否 包含目标元素 ;delete(ele)  ;       clear()  ;        values() ;       size()   ; union(set)并集 ; intersection(set) 交集 ; 

difference(set)  差集; subset(set) 子集

 class Set{
            constructor(){
                this.item = {}
            }

            has(ele){
                return this.item.hasOwnProperty(ele)
            }
            add(ele){
                if(!this.has(ele)){
                    this.item[ele] = ele
                }
                return !this.has(ele)
            }
            delete(ele){
                return delete this.item[ele]
            }
            clear(){
                this.item = {}
            }
            values(){
                return Object.values(this.item)
            }
            size(){
                return Object.values(this.item).length
            }
            // 并集
            union(set){
                let newset = new Set()
                //将两个集合分别加在新数组中
                this.values().forEach(ele=>{
                    newset.add(ele)
                })

                set.values().forEach(ele=>{
                    newset.add(ele)
                })
                return newset
            }
            // 交集
            intersection(set){
                let newset = new Set()
                // 遍历this 集合 在set集合中也存在的加入 新数组
                this.values().forEach(ele=>{
                    if(set.has(ele)){
                        newset.add(ele)
                    }
                })
                return newset
            }
            // 差集
            difference(set){
                let newset = new Set()
                //在this 集合中存在 但在 set集合中不存在的加入 新数组
                this.values().forEach(ele=>{
                    if(!set.has(ele)){
                        newset.add(ele)
                    }
                })
                return newset

            }
            // 子集
            subset(set){
                // 遍历 set集合 如果有元素 不存在于 this 集合 
                // 返回false 说明不是this 的子集
                for(let i=0; i<set.values().length; i++){
                    if(!this.has(set.values()[i])){
                        return false
                    }
                }
                
                return true
            }
        }

五、字典

① 实质上是一个对象 , 有特殊方法和要求

② 封装一个 字典:

 class Dictionay {
            constructor() {
                this.item = {}
            }
            // 新增元素
            set(key, value) {
                // 当对象含有该键值时 做赋值操作
                this.item[key] = value
            }
            // 查找字典中 是否含有目标键值
            has(key) {
                return this.item.hasOwnProperty(key)
            }
            // 移除目标key
            remove(key) {
                return delete this.item[key]
            }
            get(key) {
                return this.item[key]
            }
            clear() {
                this.item = {}
            }
            size() {
                return Object.values(this.item).length
            }
            keys() {
                return Object.keys(this.item)
            }
            values() {
                return Object.values(this.item)
            }
        }

六、树

① 定义:n个节点构成的有限集合

② 术语

---结点的度:结点子树的个数

---树的度:所有结点中  最大的结点度数

---叶子结点: 度为 0  的结点

---父节点,子节点 , 兄弟结点

---路径:结点A到结点B 途径的结点 ,路径所包含边的个数 为 路径长度

---结点的层次 : 根结点在 1层 , 任意结点的层次 是 其父结点层次+1

---树的深度: 等于 最大的结点层次

1、二叉树

① 每个结点 都只有两个子结点

② 特性:
第 i 层 最大结点数  =  2^(i-1);

深度为k的最大结点数 = 2^k - 1;

叶子结点数 = 度为2 的结点数 + 1

③ 完美二叉树

④ 完全二叉树

2、二叉搜索树

① 左子结点 的值永远小于 父节点; 右子结点 的值永远 大于 父节点

② 封装一个二叉搜索树:
 

3、排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值