0.常考的一些区别:
1.数组和链表的区别:
- 数组必须事先定义固定的长度。链表可以动态进行存储分配
- 数组是必须要有足够的连续的内存空间。链表大小不固定,扩展灵活,动态分配内存
- 复杂度
- | 数组 | 链表 |
---|---|---|
插入 | O(n) | O(1) |
删除 | O(n) | O(1) |
读取 | O(1) | O(n) |
1.栈
特点:先进后出
class Stack {
nums:number[];
constructor(){
this.nums = [];
}
push(val:number):void{ //栈顶添加元素
this.nums.push(val);
}
pop():number{ //栈顶元素弹出并返回这个元素
return this.nums.pop();
}
peek():number{ //返回栈顶的元素但不删除
return this.nums[this.nums.length - 1];
}
isEmpty():boolean{ //判断栈是否为空
return !this.nums.length;
}
size():number{ //返回栈的大小
return this.nums.length;
}
clear():void{ //清空栈
this.nums = [];
}
}
2.队列
特点:先进先出
class Queue{
nums:number[]
constructor(){
this.nums = [];
}
enqueue(val:number):void{ //向队尾添加一个元素
this.nums.push(val);
}
dequeue():number{ //移除队列第一个元素并返回
return this.nums.shift();
}
head():number{ //返回队列第一个元素
return this.nums[0];
}
tail():number{ //返回队列最后一个元素
return this.nums[this.nums.length - 1];
}
isEmpty():boolean{ //判断队列是否为空
return !this.nums.length;
}
size():number{ //返回队列的大小
return this.nums.length;
}
clear():void{ //清空队列
this.nums = [];
}
}
3.链表
链表是由一系列节点组成,每个节点都是用一个对象的引用指向它的后继,从而形成一个链
相比于数组的优势:由于数组的长度预先固定,因此再添加元素或删除元素较为困难
class ListNode { //节点类
val:number,
next:ListNode | null,
constructor(val?: number, next?: ListNode | null){
this.val = (val === undefined ? 0 : val);
this.next = (next === undefined ? null : next);
}
}
class List {
head:ListNode
constructor(val:number){
this.head.val = val;
this.head.next = null;
}
find(val:number){ //查找值为val的节点并返回
let temp = this.head;
while(temp){
if(temp.val === val){
return temp;
}
temp = temp.next;
}
}
insert(node:ListNode){
this.head.next = node;
}
}
4.排序算法
1.冒泡排序。相邻元素的比较和交换,复杂度O(n^2)
2.选择排序。每次循环找出最大或最小的与第一个交换位置。复杂度O(n^2)
3.插入排序。插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。刚开始这个小序列只包含第一个元素。然后每插入一个元素都依次和前面比较,插入到适合的位置,复杂度O(n2)
4.快速排序。设定一个中枢元素,通过一趟循环将要排序的数据分割成独立的两部分left和right,一部分的数据要比中枢元素小,一部分是比中枢元素大。然后递归依次循环该操作。复杂度O(nlog2n)
5.归并排序。把序列递归的分成短序列,递归到短序列只有一个元素或两个元素,然后吧各个有序的序列合并成一个有序的长序列。复杂度O(nlogn)
6.基数排序
7.希尔排序。把数组分割成若干个小组,然后对每个小组分别进行插入排序。每一个轮分割的数组的个数逐步减小,当h = 1时,排序就完成了。复杂度O(nlogn)
8.堆排序