前端必会算法(1)--线性数据结构及冒泡、选择以及快速排序

78 阅读4分钟

一维数据结构,即线性数据结构,包括了数组和链表;

数组

数组的特性

  1. 存储在屋里空间上的连续的

  2. 底层的数组长度是不可变的。如果一个长度为8的数组,添加第9个元素时,js引擎会向操作系统申请一个新的连续的更长的空间,再将前8位复制,并添加第9位。所以数组长度变化会消耗性能。

  3. 数组的变量,指向了数组第一个元素的位置;所有a[1]、a[2]其中的方括号标识存储地址的偏移;操作系统中,通过偏移查询数据性能最好。因此得出数组的

优点:查询性能好;

缺点:

  1. 因为空间必须是连续的,所以如果数组比较大,当系统的空间碎片较多的时候,容易存不下;空间碎片即指小的不连续的空间;
  2. 因为数组的长度是固定的,所以数组的内容添加删除时比较消耗性能;
链表

传递链表时,必须传递根节点。而每一个链表的节点,都认为自己是根节点;因为每一个节点都知道自己的指向,而不知道自己的被指向

链表的特性

1、 在空间上不是连续的;

2、 没存放一个值,都要多开销一个引用空间;

优点:

  1. 只要内存空间足够大,就能存的下,不用担心空间碎片的问题
  2. 链表的添加和删除非常的容易

缺点:

  1. 查询某个某个位置的速度慢
  2. 链表每一个节点都需要创建一个指向next的引用,浪费一些空间。当节点内数据越多的时候,这部分多开销的内存越少。

怎么创建链表?

function Node(value){
   this.value = value;
   this.next = null;
}

var a  = new Node(1);
var b = new Node(2);
var c = new Node(3);
var d = new Node(4);

a.next = b;
b.next = c;
c.next = d;
d.next = null;
线性数据结构的遍历

遍历:将一个集合中的每一个元素进行获取并查看

数组遍历:

function bian (arr){
    if(arr === null)return; // 算法中必须有严谨性判断,不允许出现报错;
    for(var i = 0;i<arr.length;i++){
         console.log(arr[i])
    }
}

链表的循环遍历:

function Node(value){
   this.value = value;
   this.next = null;
}

var Node1  = new Node(1);
var Node2 = new Node(2);
var Node3 = new Node(3);
var Node4 = new Node(4);

Node1.next = Node2;
Node2.next = Node3;
Node3.next = Node4;

function bianLink(root){
    var temo = root;
    while(true){
       if(temp != null){
         console.log(temp.value)
       }else{
         break;
       }
       temp = temp.next
    }
}
链表的递归遍历

function Node(value){
   this.value = value;
   this.next = null;
}

var Node1  = new Node(1);
var Node2 = new Node(2);
var Node3 = new Node(3);
var Node4 = new Node(4);

Node1.next = Node2;
Node2.next = Node3;
Node3.next = Node4;

// 递归遍历,必须有出口;
function bianLink(root){
   if(root === null)return;
   console.log(root.value);
   bianLink(root.next);
}
链表的逆置

链表的逆置,必须先找到最后一个节点,将其的next从null指向上一个节点,将上一个节点的next指向null;依次循环,直指根节点指向null


function Node(value){
   this.value = value;
   this.next = null;
}

var Node1  = new Node(1);
var Node2 = new Node(2);
var Node3 = new Node(3);
var Node4 = new Node(4);

Node1.next = Node2;
Node2.next = Node3;
Node3.next = Node4;
Node4.next = null;

function nizhi(root){
   if(root.next.next == null){ // 如果当前是倒数第二个节点
     root.next.next = root; // 将最后一个节点指向自己
     return root.next;
   }else{ // 其他情况
    var res = nizhi(root.next) 
    root.next.next = root; // 将下一个节点的next指向自己
    root.next = null; // 将自己指向空
    return res;
   }
}
const newRoot = nizhi(Node2)
console.log(newRoot)
function bianLink(root){
  if(root == null) return;
  console.log(root.value);
  bianLink(root.next)
}
bianLink(newRoot)
冒泡排序
  // 冒泡排序
  const arr = [4, 5, 21, 4, 8, 4, 2, 3, 0, 6, 3, 211, 9]
  // 排序的本质是比较和交换

  function compare(a, b) { //比较之后得出是否需要交换
    if (a > b) {
      return true
    } else {
      return false
    }
  }

  function exchange(arr, a, b) { // 将数组中ab位置的值进行交换
    var temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
  }

  function bubbleSort() {
    for (var j = 0; j < arr.length; j++) {
      for (var i = 0; i < arr.length -1- j; i++) {
        if (compare(arr[i], arr[i + 1])) {
          exchange(arr, i, i + 1)
        }
      }
    }
  }
  bubbleSort(arr)
  console.log(arr)
选择排序
function selectSort(arr) {
    for (var i = 0; i < arr.length; i++) {
      var maxIndex = 0;
      for (var j = 0; j < arr.length - i; j++) {
        if (compare(arr[maxIndex],arr[j])) {
          maxIndex = j;
        }
      }
      exchange(arr,maxIndex, arr.length - 1 - i)
    }
  }
  selectSort(arr)
  console.log(arr)
快速排序
function quickSort(arr, begin, end) {
    if (begin >= end - 1) { // 已经为有序数组
      return;
    }
    var left = begin;  // 左指针
    var right = end;   // 右指针
    do {
      do { left++ } while (arr[left] < arr[begin] && left < right); // 左指针自增,直到指针位置数值大于等于begin位置数值
      do { right-- } while (arr[right] > arr[begin] && left < right); // 右指针自减,直到指针位置数值小于等于begin位置数值
      if (left < right) {
        exchange(arr, left, right) // 交换左右指针位置数值
      }
    } while (left < right)
    var exchangePoint = left === right ? right - 1 : right;
    exchange(arr, begin, exchangePoint)
    quickSort(arr, begin, exchangePoint)
    quickSort(arr, exchangePoint + 1, end)
  }
  quickSort(arr, 0, arr.length)
  console.log(arr)