1. 列表-list
- 学习算法-面试和开发必备;
- 列表-待办事项;
- 使用-元素不多,不需很长排序,不需复杂查找;
- 概念-有序的数据;
- 迭代器优点-增删比 for 灵活;
- 空列表-不包含任何元素的列表;
- 列表函数-List, 列表方法-append find remove length toString insert clear contains front end prev next moveTo getElement currPos;
function List() {
this.listSize = 0;
this.pos = 0;
this.dataStore = [];
this.clear = clear;
this.find = find;
this.toString = toString;
this.insert = insert;
this.append = append;
this.remove = remove;
this.front = front;
this.end = end;
this.prev = prev;
this.next = next;
this.length = length;
this.currPos = currPos;
this.moveTo = moveTo;
this.getElement = getElement;
this.contains = contains;
}
function append(element) {
this.dataStore[this.listSize++] = element;
}
function find(element) {
for (let i = 0; i < this.dataStore.length; ++i) {
if (this.dataStore[i] === element) {
return i;
}
}
return -1;
}
function remove(element) {
var foundAt = this.find(element);
if (foundAt > -1) {
this.dataStore.slice(foundAt, 1);
--this.listSize;
return;
}
return false;
}
function length() {
return this.listSize;
}
function toString() {
return this.listSize;
}
function insert(element, after) {
var insertPos = this.find(after);
if (insertPos > -1) {
this.dataStore.splice(insertPos + 1, 0, element);
--this.listSize;
return true;
}
return false;
}
function clear() {
delete this.dataStore;
this.dataStore.length = 0;
this.listSize = this.pos = 0;
}
function contains() {
for (let i = 0; i < this.dataStore.length; ++i) {
if (this.dataStore[i] === element) {
return true;
}
}
return false;
}
function front() {
this.pos = 0;
}
function end() {
this.pos = this.listSize - 1;
}
function prev() {
if (this.pos > 0) {
--this.pos;
}
}
function next() {
if (this.pos < this.listSize) {
++this.pos;
}
}
function currPos() {
return this.pos;
}
function moveTo(position) {
this.pos = position;
}
function getElement() {
return this.dataStore[this.pos];
}
let list = new List();
list.append("小红");
list.append("小黄");
list.append("小蓝");
list.next();
for (list.front(); list.currPos() < list.length(); list.next()) {
console.log(list.getElement());
}
2. 栈-stack
- 栈-后入先出的数据结构
- 栈是特殊列表-只能在栈顶进行赠删
- 栈的例子-生活,洗盘子 代码,函数调用
- 后入先出英文-LIFO last-in-fast-out
- 栈的代码表示-Stack 方法 push pop peek length clear
function Stack() {
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
this.length = length;
this.clear = clear;
}
function push(ele) {
this.dataStore[this.top++] = ele;
}
function pop() {
return this.dataStore[--this.top];
}
function peek() {
return this.dataStore[this.top - 1];
}
function length() {
return this.top;
}
function clear() {
this.top = 0;
}
let stack = new Stack();
stack.push("小红");
stack.push("小黄");
stack.push("小蓝");
console.log("栈的长度", stack.length());
console.log("栈顶", stack.peek());
console.log("出栈", stack.pop());
console.log("出栈", stack.pop());
console.log("出栈", stack.pop());
- 利用栈实现回文算法isPalindrome-创建空栈s,参数遍历入栈push,创建新字符串为空rword,while 遍历栈列表,新字符串拼接每次出栈结果pop,返回新字符串与参数相等比较结果即为是否回文
/**
* 回文算法 racecar
* @param {String} word
*/
function isPalindrome(word) {
var s = new Stack()
for (var i = 0
s.push(word[i])
}
var rword = ""
while (s.length() > 0) {
rword += s.pop()
}
if (rword === word) {
return true
} else {
return false
}
}
var word = "racecar"
console.log(isPalindrome(word))
3. 队列-queue
- 队列-先入先出的数据结构
- 实例-现实,银行排队
- 队列描述-从队尾入队,从队首出队
- 优先队列-例子,急诊
- 队列代码-Queue 队列方法-enqueue,dequeue,front,back,empty,toString
function Queue() {
this.dataStore = []
this.enqueue = enqueue
this.dequeue = dequeue
this.front = front
this.back = back
this.toString = toString
this.empty = empty
}
function enqueue(ele) {
this.dataStore.push(ele)
}
function dequeue() {
return this.dataStore.shift()
}
function front() {
return this.dataStore[0]
}
function back() {
return this.dataStore[this.dataStore.length - 1]
}
function empty() {
return this.dataStore.length === 0
}
function toString() {
var reStr = ""
for (var i = 0
reStr += this.dataStore[i] + "\n"
}
return reStr
}
var queue = new Queue()
queue.enqueue("小红")
queue.enqueue("小黄")
queue.enqueue("小蓝")
console.log(queue.toString())
console.log("出队:", queue.dequeue(), "出队结果:", queue.toString())
// 方块舞-舞伴配对
var manDancers = new Queue()
manDancers.enqueue("小张")
manDancers.enqueue("小李")
var womanDancers = new Queue()
womanDancers.enqueue("小红")
womanDancers.enqueue("小黄")
function getDancers() {
return "♂" + manDancers.dequeue() + "♀" + womanDancers.dequeue()
}
console.log("一队舞伴:", getDancers())
console.log("二队舞伴:", getDancers())
// 急诊病患优先出列-优先队列
function Patient(name, code) {
this.name = name
this.code = code
}
function dequeuePatient() {
var priority = 0
for (var i = 0
if (this.dataStore[i].code > this.dataStore[priority].code) {
priority = i
}
}
return this.dataStore.splice(priority, 1)
}
function toStringPatient() {
var reStr = ""
for (var i = 0
reStr += this.dataStore[i].name + " code: " + this.dataStore[i].code + "\n"
}
return reStr
}
let pa1 = new Patient("小红", 1)
let pa2 = new Patient("小黄", 8)
let pa3 = new Patient("小蓝", 3)
let pa4 = new Patient("小张", 5)
let pa5 = new Patient("小李", 1)
let pa6 = new Patient("小王", 7)
let queuePatient = new Queue()
queuePatient.toString = toStringPatient
queuePatient.dequeue = dequeuePatient
queuePatient.enqueue(pa1)
queuePatient.enqueue(pa2)
queuePatient.enqueue(pa3)
queuePatient.enqueue(pa4)
queuePatient.enqueue(pa5)
queuePatient.enqueue(pa6)
console.log("第一个被诊治的:", queuePatient.dequeue())
console.log("剩余队列:\n", queuePatient.toString())
console.log("第二个被诊治的:", queuePatient.dequeue())
console.log("剩余队列:\n", queuePatient.toString())
4. 链表-列表中元素指向下一个元素,组成链条 使用链表原因-数组不是组织数据最佳结构 链表优点-插入删除速度比数组快,只需要改变元素指向来进行元素增删 链表实例-现实自行车链条 双向链表-链表中元素之间指向对方;
5. 字典-dictionary
- 字典-
键-值对形式为元素存储的列表
- 字典例子-电话簿,通过名字查找手机号;
- 字典代码-Dictionary,方法-add find remove showAll count clear; 排序-根据键值 sort;
function Dictionary() {
this.dataStore = []
this.add = add
this.find = find
this.remove = remove
this.showAll = showAll
this.count = count
this.clear = clear
}
function add(key, value) {
this.dataStore[key] = value
}
function find(key) {
return this.dataStore[key]
}
function remove(key) {
delete this.dataStore[key]
}
function showAll() {
var dataKeys = Object.keys(this.dataStore).sort()
for (var key in dataKeys) {
console.log(dataKeys[key] + "-->" + this.dataStore[dataKeys[key]])
}
}
function count() {
return Object.keys(this.dataStore).length
}
function clear() {
var dataKeys = Object.keys(this.dataStore)
for (var key in dataKeys) {
delete this.dataStore[dataKeys[key]]
}
}
var d = new Dictionary()
d.add("小红", 18)
d.add("小黄", 19)
d.add("小蓝", 20)
console.log("小红", d.find("小红"))
d.showAll()
d.remove("小红")
console.log("个数", d.count())
d.clear()
console.log("个数", d.count())
6. 散列-HashTable
- 散列-数组长度预先设定,将键均匀分布的特殊列表;
- 碰撞-两个键相同的情况;
- 开链法-两个键相同保存位置一样。开辟第二数组;
- 线性探测法-开放寻址散列,查找散列位置如果没有当前位置没有继续寻找下一个位置。存储数据较大较适合。
- 方法选择-数组大小>=1.5数据(开链法),数组大小>=2数据(线性探索法);
- 防止碰撞-设置质数长度数组;
- 散列-普通
function HashTable() {
this.table = new Array(137);
this.simpleHash = simpleHash;
this.put = put;
this.get = get;
this.showDistro = showDistro;
this.betterHash = betterHash;
}
function simpleHash(data) {
var total = 0;
for (var i = 0; i < data.length; i++) {
total += data.charCodeAt(i);
}
return total % this.table.length;
}
function put(data) {
var pos = this.betterHash(data);
this.table[pos] = data;
}
function get(key) {
return this.table[this.betterHash(key)];
}
function showDistro() {
var n = 0;
for (var i = 0; i < this.table.length; i++) {
if (this.table[i] != undefined) {
console.log("键值是-》" + i + "值是【" + this.table[i] + "】");
}
}
}
function betterHash(data) {
var H = 31;
var total = 0;
for (let i = 0; i < data.length; i++) {
total += H * total + data.charCodeAt(i);
}
if (total < 0) {
total += this.table.length - 1;
}
return total % this.table.length;
}
var hd = new HashTable();
hd.put("China");
hd.put("Japan");
hd.put("America");
hd.put("niCha");
hd.put("12345");
hd.showDistro();
function HashTable() {
this.table = new Array(137)
this.simpleHash = simpleHash
this.put = put
this.get = get
this.showDistro = showDistro
this.betterHash = betterHash
this.buildChains = buildChains
}
// 开链法
function buildChains() {
for (let i = 0
this.table[i] = new Array()
}
}
/**
* 除留余数法
* @param {String} data
*/
function simpleHash(data) {
var total = 0
for (var i = 0
total += data.charCodeAt(i)
}
return total % this.table.length
}
function put(data) {
// 开链法插入
var pos = this.simpleHash(data)
var index = 0
if (this.table[pos][index] == undefined) {
this.table[pos][index] = data
index++
} else {
while (this.table[pos][index] != undefined) {
++index
}
this.table[pos][index] = data
}
}
function get(key) {
return this.table[this.simpleHash(key)]
}
function showDistro() {
var n = 0
for (var i = 0
if (this.table[i][0] != undefined) {
console.log("键值是-》" + i + "值是【" + this.table[i] + "】")
}
}
}
function betterHash(data) {
var H = 31
var total = 0
for (let i = 0
total += H * total + data.charCodeAt(i)
}
if (total < 0) {
total += this.table.length - 1
}
return total % this.table.length
}
var hd = new HashTable()
hd.buildChains()
hd.put("China")
hd.put("Japan")
hd.put("America")
hd.put("niCha")
hd.put("12345")
hd.showDistro()
function HashTable() {
this.table = new Array(137);
this.simpleHash = simpleHash;
this.put = put;
this.get = get;
this.showDistro = showDistro;
}
function simpleHash(data) {
var total = 0;
for (var i = 0; i < data.length; i++) {
total += data.charCodeAt(i);
}
return total % this.table.length;
}
function put(data) {
var pos = this.simpleHash(data);
if (this.table[pos] == undefined) {
this.table[pos] = data;
} else {
while (this.table[pos] != undefined) {
pos++;
}
this.table[pos] = data;
}
}
function get(key) {
var hash = this.simpleHash(key);
console.log(hash);
for (var i = 0; i < this.table.length; i++) {
if (this.table[i] == key) {
return i;
}
}
return undefined;
}
function showDistro() {
var n = 0;
for (var i = 0; i < this.table.length; i++) {
if (this.table[i] != undefined) {
console.log("键值是-》" + i + "值是【" + this.table[i] + "】");
}
}
}
var hd = new HashTable();
hd.put("China");
hd.put("Japan");
hd.put("America");
hd.put("niCha");
hd.put("12345");
console.log("niCha的位置", hd.get("niCha"));
hd.showDistro();
7. 集合-Set
function Set() {
this.dataStore = new Array();
this.add = add;
this.remove = remove;
this.show = show;
this.union = union;
this.intersect = intersect;
this.difference = difference;
this.subset = subset;
this.contains = contains;
this.size = size;
}
function add(data) {
if (this.dataStore.indexOf(data) != -1) return false;
this.dataStore.push(data);
}
function remove(data) {
var pos = this.dataStore.indexOf(data);
if (pos == -1) return false;
this.dataStore.splice(pos, 1);
}
function show() {
console.log(this.dataStore);
return this.dataStore;
}
let names = new Set();
names.add("小红");
names.add("小红");
names.add("小黄");
names.add("小蓝");
names.add("老王");
function contains(data) {
return this.dataStore.indexOf(data) != -1;
}
function union(set) {
var temSet = new Set();
for (let i = 0; i < this.dataStore.length; i++) {
temSet.add(this.dataStore[i]);
}
for (let i = 0; i < set.dataStore.length; i++) {
if (!temSet.contains(set.dataStore[i])) {
temSet.dataStore.push(set.dataStore[i]);
}
}
return temSet;
}
function intersect(set) {
var temSet = new Set();
for (let i = 0; i < this.dataStore.length; i++) {
if (set.contains(this.dataStore[i])) {
temSet.add(this.dataStore[i]);
}
}
return temSet;
}
function difference(set) {
var temSet = new Set();
for (let i = 0; i < this.dataStore.length; i++) {
if (!set.contains(this.dataStore[i])) {
temSet.add(this.dataStore[i]);
}
}
return temSet;
}
function size() {
return this.dataStore.length;
}
function subset(set) {
if (this.size() < set.size()) return false;
for (let i = 0; i < set.dataStore.length; i++) {
if (!this.contains(set.dataStore[i])) {
return false;
}
}
return true;
}
let cit = new Set();
cit.add("1");
cit.add("2");
cit.add("3");
cit.add("小红");
cit.union(names).show();
cit.intersect(names).show();
cit.difference(names).show();
let it = new Set();
it.add("1");
console.log(cit.subset(it));
8. 二叉树-BST
- 二叉树-非线性分层数据结构;
- 特点-子节点不超过两个;
- 二叉查找树-特殊二叉树,较小的值保存在左节点;
- 二叉查找树代码
function Node(data, left, right) {
this.data = data
this.left = left
this.right = right
this.show = show
}
function show() {
return this.data
}
function BST() {
this.root = null
this.insert = insert
this.inOrder = inOrder
this.getSmallest = getSmallest
this.getMax = getMax
this.find = find
this.remove = remove
}
function insert(data) {
var n = new Node(data, null, null)
if (this.root == null) {
this.root = n
} else {
var current = this.root
var parent
while (true) {
parent = current
if (data < current.data) {
current = current.left
if (current == null) {
parent.left = n
break
}
} else {
current = current.right
if (current == null) {
parent.right = n
break
}
}
}
}
}
function inOrder(node) {
if (node != null) {
inOrder(node.left)
console.log(node.data)
inOrder(node.right)
}
}
function getSmallest(root) {
var current = this.root || root
while (current.left != null) {
current = current.left
}
console.log(current.data)
return current
}
function getMax() {
var current = this.root || root
while (current.right != null) {
current = current.right
}
console.log(current.data)
return current
}
function find(data) {
var current = this.root
while (current.data != null) {
if (data == current.data) {
return current
} else if (data < current.data) {
current = current.left
} else if (data > current.data) {
current = current.right
}
}
return null
}
function remove(data) {
removeNode(this.root, data)
}
function removeNode(node, data) {
if (node == null) return null
if (node.data == data) {
if (node.left == null && node.right == null) {
return null
}
if (node.left == null) {
return node.right
}
if (node.right == null) {
return node.left
}
var tempNode = getSmallest(node.right)
node.data = tempNode.data
node.right = removeNode(node.right, tempNode.data)
return node
} else if (data < node.data) {
node.left = removeNode(node.left, data)
return node
} else {
node.right = removeNode(node.right, data)
return node
}
}
var nums = new BST()
nums.insert(50)
nums.insert(10)
nums.insert(19)
nums.insert(30)
nums.insert(99)
nums.insert(55)
nums.insert(11)
nums.inOrder(nums.root)
console.log("-------------")
nums.getSmallest()
nums.getMax()
console.log("-------------")
console.log(nums.find(99))
console.log("-------------")
nums.remove(11)
nums.inOrder(nums.root)