数据结构与算法
1、数组
数组特性:
- 1、查找速度很快,可以通过索引快速查找元素。
- 2、插入,删除操作速度相对较慢。因为插入,删除时需要对该位置后方的所有元素进行位移
- 3、数组的创建通常需要申请一段连续的内存空间,并且大小是固定的,所以当当前数组不能满足容量需求时,需要扩容(一般情况下hi申请一个更大的数组,比如2倍,然后将原数组中的元素复制过去)
2、栈
栈特性:
- 1、是一种受限的数据结构,只有一个口进行进栈和出栈,先进后出的原则
栈的常见操作
- 1、push():添加一个新元素到栈顶位置
- 2、pop():移除栈顶元素,同时返回被移除的元素
- 3、peek():返回栈顶元素,不对栈进行任何修改
- 4、isEmpty():如果栈没有任何元素返回true,否则返回false
- 5、size():返回栈里元素个数,与数组的length方法类似
- 6、toString():将栈结构以字符串的形式返回
function Stack(){
// 栈的属性
this.items = []
//栈的相关操作
// 1、将栈元素压入栈
Stack.prototype.push = function(element){
this.items.push(element)
}
// 2、从栈中取出元素
Stack.prototype.pop = function(){
return this.items.pop()
}
// 3、查看一下栈顶元素
Stack.prototype.peek =function(){
return this.items[this.items.length -1]
}
// 4、判断栈是否为空
Stack.prototype.isEmpty = function(){
return this.items.length == 0
}
// 5、获取栈中元素的个数
Stack.prototype.size = function(){
return this.items.length
}
// 6、toString方法
Stack.prototype.toString = function(){
let result = ''
for(let i=0; i<this.items.length; i++){
result += this.items[i] + ' '
}
return result
}
}
栈的应用(十进制转成二进制)
function dec2bin(decNumber){
//1.定义栈对象
let stack = new Stack()
// 2、循环操作
while(decNumber > 0){
//2.1获取余数,压入栈中
stack.push(decNumber % 2)
// 2.2获取整除后的结果,作为下一次运行的数字
decNumber = Math.floor(decNumber / 2)
}
// 3、从栈中取数0和1
let binaryString = ''
while (!stack.isEmpty()) {
binaryString += stack.pop()
}
return binaryString
}
// 测试十进制转二级制
console.log(dec2bin(100))
3、队列
队列特性:
- 1、它是一种受限制的线性表,先进先出
- 2、受限之处在于它只允许在表前端进行删除
- 3、而在表后端进行插入操作
队列的常见操作
- 1、enqueue():向队列尾部添加一个或多个新项
- 2、dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素
- 3、front():返回队列中第一个元素——最先被添加,也将是最先被移除的元素,队列不做任何变动(不移除元素,会返回元素信息——与stack类额peek方法非常类似)
- 4、isEmpty():如果队列中不包含任何元素,返回true,否则返回false
- 5、size():返回队列中包含元素的个数,与数组的length相似
- 6、toString():将队列中的内容转成字符串形式
基于数组进行封装
function Queue(){
//属性
this.items =[]
//方法
// 1、将元素加入到队列中
Queue.prototype.enqueue = function(element){
this.items.push(element)
}
// 2、删除队列中的前端元素
Queue.prototype.dequeue = function(){
return this.items.shift()
}
// 3、查看队列中前端元素
Queue.prototype.front = function(){
return this.items[0]
}
// 4、查看队列是否为空
Queue.prototype.isEmpty = function(){
return this.items.length == 0
}
// 5、查看队列中元素个数
Queue.prototype.size = function(){
return this.items.length
}
// 6、toString队列
Queue.prototype.toString = function(){
let result = ''
for(let i=0; i<this.items.length; i++){
result += this.items[i] + ' '
}
return result
}
}
面试题算法示例
规则:几个朋友一起玩一个游戏,围成一圈,开始数数,数到某一个数字的人自动淘汰,最后剩下的那个人获胜,请问最后获胜的人是原来在哪一个位置上的人
function passGame(nameList, num){
// 1、创建一个队列结构
let queue = new Queue()
//2、将所有人一次加入队列
for(let i=0;i<nameList.length;i++){
queue.enqueue(nameList[i])
}
// 3、开始数数,
while (queue.size() > 1) {
// 不是num的时候,重新加入到队列末尾
// 如果是num这个数字时,将其从队列中删除
// 3.1 num之前的人重新放入到队列末尾
for(let i=0;i<num-1;i++){
queue.enqueue(queue.dequeue())
}
// 3.2 对应num的人,直接冲队列删除掉
queue.dequeue()
}
// 4、剩下的那个人
let endName = queue.front()
return {name:endName,index:nameList.indexOf(endName)}
}
//测试击鼓出传花
let nameList = ['张三','李四','王五','小明','小红']
console.log(passGame(nameList,3))
优先级队列
特点
- 1、优先级队列,在插入一个元素的时候会考虑该数据的优先级
- 2、和其他数据优先级进行比较
- 3、比较完成之后,可以得出该元素在队列中的正确位置 主要考虑的问题:
- 1、每个元素不再是一个数据,而且包含数据的优先级
- 2、在添加方式中,根据优先级放入正确的位置
生活中优先级队列应用
- 1、登机的顺序:头等舱,商务舱优先于经济舱登记,老人,孕妇优先登机
- 2、医院急诊候诊:医生优先处理病情比较严重的病人。
优先级队列封装
function PriorityQueue(){
//在PriorityQueue重新创建一个类,可以理解成内部类
function QueueElement(element,priority){
this.element = element;
this.priority = priority
}
// 封装属性
this.items = []
// 插入方法
PriorityQueue.prototype.enqueue = function(element,priority){
// 1、创建QueueElement对象
let queueElement = new QueueElement(element,priority)
//2、判断队列是否为空
if(this.items.length == 0){
this.items.push(queueElement)
}else{
let addad = false;
for(let i=0;i<this.items.length;i++){
if(queueElement.priority < this.items[i].priority){
this.items.splice(i,0,queueElement)
addad = true;
break
}
}
if(!addad){
this.items.push(queueElement)
}
}
}
//其他和普通队列一样
}