GoMind Hub

算法

计算机知识思维导图:算法。网页展示前三层结构,可在线查看完整脑图并下载 GoMind 文件。

2026-08-25

计算机知识学习资料思维导图
## 算法
### 算法
#### Untitled node
#### Untitled node
#### Untitled node
#### O(1)<O(lgN)<O(N)<O(N*lgN)<O(n²)<O(n3)<O(2ⁿ)
#### 递归
##### 应用场景
##### 实现
#### 排序算法
##### 比较排序
##### 非比较排序
#### 链表
##### 链表逆序
#### 量级
##### 2^20 约等于 100万,即百万个字节约等于1M
##### 2^30 约等于 10亿,即10亿个字节约等于1G
#### 数据结构
##### Skiplist
##### Tree
##### HashTable
##### 性能对比

> 仅展示前三层结构;请在线查看完整脑图或下载 GoMind 文件。

算法

算法
Untitled node
Untitled node
Untitled node
O(1)<O(lgN)<O(N)<O(N*lgN)<O(n²)<O(n3)<O(2ⁿ)
爬楼梯问题
母牛生仔问题
应用场景
时间复杂度为O(n),空间复杂度为O(1)
function fibonacci(n){  

    var a,b,res;  

    a = b = 1;  

    if(n == 0){  

        return 0;  

    }  

    if(n == 1 || n == 2){  

        return 1;  

    }   

    for(var i=2;i<n;i++){  

        res = a + b;  

        a = b;  

        b = res;  

    }  

    return res;  

}
时间复杂度为O(n),空间复杂度为O(n)
function fibo(x){

    var arr = new Array(x);

	

	arr[0] = 1;

	arr[1] = 1;

	for(var index=2;index<x;index++){

	   arr[index] = arr[index-1]+arr[index-2];

	}

	

	var result = 0;

	arr.forEach((item)=>{

	   result+=item;

	});

	return result;

  }



  fibo(5);
时间复杂度为 O(N*lgN)
function Fibonacci (n) {

  if ( n <= 1 ) {return 1};



  return Fibonacci(n - 1) + Fibonacci(n - 2);

}



Fibonacci(10) // 89

Fibonacci(100) // 堆栈溢出

Fibonacci(500) // 堆栈溢出
实现
递归
冒泡排序 O(n²)
function bubbleSort(arr) {

    var len = arr.length;

    for (var i = 0; i < len - 1; i++) {

        for (var j = 0; j < len - 1 - i; j++) {

            if (arr[j] > arr[j+1]) {        // 相邻元素两两对比

                var temp = arr[j+1];        // 元素交换

                arr[j+1] = arr[j];

                arr[j] = temp;

            }

        }

    }

    return arr;

}
快速排序
每次取序列中的第一个数作为基准,将序列分为两部分,左边的数要小于基准值,右边的数大于基准值。具体做法是使用两个指针前后扫码序列,后面的指针先扫,若发现后面的值小于基准值则交换,接着前面的指针开始扫描,若前面的值大于基准值则交换。



巧妙之处在于partition方法中的置换



public static int partition(int[] arr,int start,int end){



        int base = arr[start];



        while(start<end){

            while(arr[end]>base && start<end){

                end--;

            }



            arr[start] = arr[end];



            while(arr[start]<=base && start<end){

                start++;

            }



            arr[end] = arr[start];

        }



        arr[start] = base;



        return start;

    }



    public  static void quickSort(int[] arr,int low,int high) {

        if (low < high) {

            int pivot = partition(arr, low, high);        //将数组分为两部分

            quickSort(arr, low, pivot - 1);                   //递归排序左子数组

            quickSort(arr, pivot + 1, high);                  //递归排序右子数组

        }

    }
交换排序
简单插入排序 O(n²)
从第一个元素开始,该元素可以认为已经排好序。取出下一个元素,在序列中从后向前扫描,如果该元素大于新元素,则将该元素移动到下一位。



function insertionSort(arr) {

    var len = arr.length;

    var preIndex, current;

    for (var i = 1; i < len; i++) {

        preIndex = i - 1;

        current = arr[i];

        while (preIndex >= 0 && arr[preIndex] > current) {

            arr[preIndex + 1] = arr[preIndex];

            preIndex--;

        }

        arr[preIndex + 1] = current;

    }

    return arr;

}
希尔排序
插入排序
简单选择排序 O(n²)
没轮获取第一个数作为最大或最小值,再以该数与其他数字对比,对比后记录下最小或最大值的小标,每轮循环结束后将该下标与每轮中的第一个元素进行交换,依次循环直到结束



function selectionSort(arr) {

    var len = arr.length;

    var minIndex, temp;

    for (var i = 0; i < len - 1; i++) {

        minIndex = i;

        for (var j = i + 1; j < len; j++) {

            if (arr[j] < arr[minIndex]) {     // 寻找最小的数

                minIndex = j;                 // 将最小数的索引保存

            }

        }

        temp = arr[i];

        arr[i] = arr[minIndex];

        arr[minIndex] = temp;

    }

    return arr;

}
左边子节点为 2*n +1
右边子节点为 2*n + 2
父节点为 [n/2] (向下取整)
若节点下标为 n (n>1)
堆排序
堆排序就是利用堆得性质堆数组进行排序,待排序元素存放在一个数组Arr[0 ……n] 中,将Arr用一颗完全二叉树来表示,数组第一个元素就是完全二叉树的根,后面依次按层从左至右为,左孩子,右孩子,任意节点Arr[ i ] 的左孩子是Arr[ 2i+1 ],右孩子是 Arr[ 2i+2 ]



--------------------- 

作者:askunix_hjh 

来源:CSDN 

原文:https://blog.csdn.net/m0_37925202/article/details/80818561 

版权声明:本文为博主原创文章,转载请附上博文链接!
选择排序
二路归并排序
多路归并排序
归并排序
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。 



归并排序是一种稳定的排序方法。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间。
比较排序
基数排序
计数排序
桶排序
非比较排序
排序算法
链表逆序
public class LinkedListReverse {



    static class ListNode{

        int data;

        ListNode next;

        public ListNode(int data){

            this.data = data;

        }

    }



    public static ListNode reverse(ListNode head){

        if (head == null){

            return null;

        }

        ListNode cur = head;

        ListNode oldHead = null;

        ListNode newHead = null;

        while(cur != null){

            oldHead = cur.next;

            cur.next = newHead;

            newHead = cur;

            cur = oldHead;

        }



        return newHead;

    }



    public static void main(String[] args) {

        // 测试

        ListNode node1 = new ListNode(1);

        ListNode node2 = new ListNode(2);

        ListNode node3 = new ListNode(3);

        node1.next = node2;

        node2.next = node3;

        ListNode head = new ListNode(0);

        head = reverse(node1);

        System.out.print(head.data+" "+head.next.data+" "+head.next.next.data);

    }



}

--------------------- 

作者:evillist 

来源:CSDN 

原文:https://blog.csdn.net/evillist/article/details/77124522 

版权声明:本文为博主原创文章,转载请附上博文链接!
链表
2^20 约等于 100万,即百万个字节约等于1M
2^30 约等于 10亿,即10亿个字节约等于1G
量级
Skiplist
AVL
AVL树是最早被发明的自平衡二叉查找树, 高度平衡树
RedBlackTree
B+Tree
Tree
HashTable
1. skiplist和各种平衡树(如AVL、红黑树等)的元素是有序排列的,而哈希表不是有序的。因此,在哈希表上只能做单个key的查找,不适宜做范围查找。所谓范围查找,指的是查找那些大小在指定的两个值之间的所有节点。
2. 在做范围查找的时候,平衡树比skiplist操作要复杂。在平衡树上,我们找到指定范围的小值之后,还需要以中序遍历的顺序继续寻找其它不超过大值的节点。如果不对平衡树进行一定的改造,这里的中序遍历并不容易实现。而在skiplist上进行范围查找就非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现。
3. 平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而skiplist的插入和删除只需要修改相邻节点的指针,操作简单又快速。
4. 从内存占用上来说,skiplist比平衡树更灵活一些。一般来说, 平衡树每个节点包含2个指针(分别指向左右子树),而skiplist每个节点包含的指针数目平均为1/(1-p),具体取决于参数p的大小。如果像Redis里的实现一样,取p=1/4,那么平均每个节点包含1.33个指针,比平衡树更有优势。
5. 查找单个key,skiplist和平衡树的时间复杂度都为O(log n),大体相当; 而哈希表在保持较低的哈希值冲突概率的前提下,查找时间复杂度接近O(1),性能更高一些。所以我们平常使用的各种Map或dictionary结构,大都是基于哈希表实现的。
6. 从算法实现难度上来比较,skiplist比平衡树要简单得多
性能对比
数据结构