1. 程式人生 > >排序算法之選擇排序類

排序算法之選擇排序類

什麽 art esc bubuko .com align tar order spa

簡單選擇排序

一、工作原理

圖解

技術分享圖片

我們可以從圖上可以看出,我們先循環找出最小的元素。我們的第二個循環是找出最小的元素,第一個循環是負責交換值的,第一趟排序外層循環的指針指向數組的第一個,這個時候我們找出數組的最小值,和外層指針交換數值,就把最小的放在第一個,後面的同理。

註意:

1、重點在於先循環找出最小的值,再去交換;

二、源代碼

<?php

	function SelectSort(array &$arr)
	{
		$length = count($arr);
		for($i = 0; $i < $length - 1; $i++){
			$min = $i;
			for($j = $i+1; $j < $length; $j++){
				if( $arr[$min] > $arr[$j]){
					$min = $j;
				}
			}
			if($min != $i){
				$temp = $arr[$min];
				$arr[$min] = $arr[$i];
				$arr[$i] = $temp;
			}
		}
		var_dump($arr);
	}
	$arr = [5,2,6,0,3,9,1,7,4,8];
	SelectSort($arr);

三、性能分析

排序類別 排序方法 時間復雜度 空間復雜度 穩定性
平均情況 最壞情況 最好情況
選擇排序類 簡單選擇排序 O(n2) O(n2) O(1) 穩定


堆排序

一、工作原理

1、什麽是大頂堆,和小頂堆?

  堆排序是在完全二叉樹的結構上建立的。完全二叉樹就是每一個父節點都有左孩子和右孩子兩個子節點並且他的葉節點是有順序的,從左到右是連續的;

  技術分享圖片

  上圖就是完全二叉樹,大頂堆就是根節點是二叉樹裏面最大的值並且父節點的值要比兩個子節點的值都要大;小頂堆反過來。

2、具體的流程

  註意:我以大頂堆為例

  第一步:我們現將目標數組,構建成完全二叉樹的結構;

  第二步:我們將已經轉化後的完全二叉樹的根節點和數組最後的一個元素進行互換位置,換完了以後,有可能打破完全二叉樹的結構,這時我們再將目標數組構建大頂堆,但是要去掉數組的最大值,也就是數組的長度減1。

3、圖解

技術分享圖片

二、源代碼

<?php
	/**
	*Description:用於兩個數之間的交換
	*@Param:int a
	*@Param:int b
	*@Param:array arr
	*/
	function swap(array &$arr, $a, $b)
	{
		$temp = $arr[$a];
		$arr[$a] = $arr[$b];
		$arr[$b] = $temp;
	}
	/**
	*Description:將原數組構建為一個大頂堆
	*@Param:int start  
	*@Param:int end 
	*@Param:array arr
	**/
	function HeapAdjest(array &$arr, $start, $end)
	{
		$temp = $arr[$start];
		//左孩子2 * $start + 1,右孩子2 * $start + 2
		for($i = 2 * $start + 1; $i <= $end; $i = $i * 2 + 1){
			if($i != $end && $arr[$i] < $arr[$i + 1]){
				$i++;//轉換為右孩子
			}
			if($temp > $arr[$i]){
				break; //滿足大頂堆
			}
			//將根節點設置為子節點較大的值
			$arr[$start] = $arr[$i];
			$start = $i;
		}
		$arr[$start] = $temp;
	}
	/**
	*Description:堆排序的主函數
	*@Param:array arr
	**/
	function HeapSort(array &$arr)
	{
		$len = count($arr);
		//先將數組構造成大根堆,由於是完全二叉樹,所以這裏用floor($count/2)-1
		for ($i = floor($len / 2) - 1; $i >= 0; $i--){
			HeapAdjest($arr, $i, $len);
		}
		for ($i = $len - 1; $i >= 0; $i--){
			//將堆頂元素與最後一個元素交換,獲取到最大元素(交換後的最後一個元素),將最大元素放到數組末尾
			swap($arr, 0, $i);
			//經過交換,將最後一個元素(最大元素)脫離大根堆,交換後有可能破壞完全二叉樹的結構,繼續構建二叉樹
			HeapAdjest($arr, 0, $i - 1);
		}
	}
	$arr = array(9,1,5,8,3,7,4,6,2);
	HeapSort($arr);
	var_dump($arr);

註意:

1、在構建大頂堆的時候,我們先要判斷左右孩子那個大,在和大的交換位置;

三、性能分析

排序類別 排序方法 時間復雜度 空間復雜度 穩定性
平均情況 最壞情況 最好情況
選擇排序類 堆排序 O(n*log2n) O(n*log2n) O(n*log2n) O(1) 不穩定

排序算法之選擇排序類