1. 程式人生 > >js 資料結構

js 資料結構

二叉樹和二叉查詢樹

樹是電腦科學中經常用到的一種資料結構。樹是一種非線性的資料結構,以分層的方式儲存資料。 二叉樹每個節點的子節點不允許超過兩個。一個父節點的兩個子節點分別稱為左節點和右節點,通過將子節點的個數限定為2,可以寫出高效的程式在樹中插入、查詢和刪除資料。 二叉查詢樹(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; // inOrder是遍歷BST的方式
}

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;
		}
	  }
    }
  }
}

images

遍歷BST的方式有三種:中序遍歷(以升序訪問樹中所有節點,先訪問左節點,再訪問根節點,最後訪問右節點)、先序遍歷(先訪問根節點,再以同樣的方式訪問左節點和右節點)、後序遍歷(先訪問葉子節點,從左子樹到右子樹,再到根節點)

排序演算法

基本排序演算法

基本排序演算法,其核心思想是指對一組陣列按照一定的順序重新排列。重新排列時用到的技術是一組巢狀的for迴圈。其中外迴圈會遍歷陣列的每一項,內迴圈則用於比較元素。

氣泡排序

氣泡排序是一種簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果它們的順序錯誤就把它們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。

function bubbleSort (arr) {
	var i = arr.length;
	while (i > 0) {
		var pos = 0
		for (var j = 0; j < i; j++) {
			if (arr[j] > arr[j+1]){
				pos = j
				var temp = arr[j]
				arr[j] = arr[j+1]
				arr[j+1] = temp
			}
		}
		i = pos
	}
	return arr
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(bubbleSort(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

images

選擇排序

選擇排序(Selection-sort)是一種簡單直觀的排序演算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

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[minIndex]
		arr[minIndex] = arr[i]
		arr[i] = temp
	}
	return arr
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(selectionSort(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

images

插入排序

插入排序(Insertion-Sort)的演算法描述是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在實現上,通常採用in-place排序(即只需用到O(1)的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,為最新元素提供插入空間。、

function insertSort (arr) {
	var len = arr.length
	for (i = 1; i < len; i++) {
		var key = arr[i]
		var j = i - 1
		while (j >= 0 && arr[j] > key) {
			arr[j+1] = arr[j]
			j--;
		}
		arr[j+1] = key
	}
	return arr
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];

images

快速排序

快速排序是處理 大資料集最快的排序演算法之一。它是一種分而治之的演算法,通過遞迴的方法將資料依次分解為包含較小元素和較大元素的不同子序列。該演算法不斷重複這個步驟知道所有資料都是有序的。 這個演算法首先要在列表中選擇一個元素作為基準值。資料排序圍繞基準值進行,將列表中小於基準值的元素移到陣列的底部,將大於基準值的元素移到陣列的頂部。

function qSort (arr) {
	if (arr.length == 0) {
		return []
	}
	var left = []
	var right = []
	var pivot = arr[0]
	for (var i = 1; i < arr.length; i++) {
		if (arr[i] < pivot) {
			left.push(arr[i])
		} else {
			right.push(arr[i])
		}
	}
	return qSort(left).concat(pivot, qSort(right))
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(qSort(arr));

檢索演算法

在列表中查詢資料有兩種方式:順序查詢和二分查詢。順序查詢適用於元素隨機排列的列表;二分查詢適用於元素已排序的列表。二分查詢效率更高,但是必須在進行查詢之前花費額外的時間將列表中的元素排序。

順序查詢

對於查詢資料,最簡單的方法就是從列表的第一個元素開始對列表元素逐個進行判斷,直到找到了想要的結果,或者直到列表結尾也沒有找到。這種方法稱為順序查詢,有時也被稱為線性查詢。

function seqSearch (arr, data) {
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] == data) {
      return i;
    }
  }
  return -1;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(seqSearch(arr, 15))

二分查詢

二分法查詢,也稱折半查詢,是一種在有序陣列中查詢特定元素的搜尋演算法。查詢過程可以分為以下步驟:

  • 首先,從有序陣列的中間的元素開始搜尋,如果該元素正好是目標元素(即要查詢的元素),則搜尋過程結束,否則進行下一步。
  • 如果目標元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半區域查詢,然後重複第一步的操作。
  • 如果某一步陣列為空,則表示找不到目標元素。
function binSearch (arr, data) {
	var low = 0;
	var high = arr.length - 1
	while (low <= high) {
		var middle = Math.floor((low + high) / 2)
		if (arr[middle] < data) {
			low = middle + 1
		} else if (arr[middle] > data) {
			high = middle - 1
		} else {
			return middle
		}
	}
	return -1
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(binSearch(arr, 15))