數據結構算法 - 線性表的實現

數組 是線性表數據結構中 順序存儲 的具體實現。用一組 連續 的內存空間,存儲 相同類型 的數據

鏈表 是線性表數據結構中 鏈式存儲的具體實現。用 節點指針 把各個節點串聯在一起

數組的基本操作

  • 在指定位置插入元素
  • 刪除指定元素
  • 查找值等於給定值的元素
  • 查找數組小標爲 index 的元素

根據 線性表 順序存儲的數據結構特徵,我們可以知道,數組的 插入、刪除 時間複雜度爲 O(n),因爲涉及到數據的搬移操作;數組的 根據下標訪問元素 的時間複雜度爲 O(1),這是 連續的內存空間 帶來的優勢,根據 尋址公式 我們可以很容易的找到指定下標的內存地址

數組的代碼實現 (PHP)

class MyArray
{
	// 數組大小
	private $size;
    // 當前數組長度
    private $len;
    // 數組的數據
    private $data;
    
    /**
     * 初始化數組
	 */
    public function __construct($size = 0)
    {
		if ($size <= 0) throw new Exception('Invalid Array size');
		
		$this->size = $size;
		$this->len = 0;
		$this->data = array();
	}
	
	/**
	 * 判斷數組是否已滿
	 */
	private function full()
	{
		if ($this->size == $this->len) return true;

		return false;
	}
	
    /**
	 * 索引是否超出範圍
	 */
	private function outOfRange($index)
	{
		if ($index < 0 || $index >= $this->len) return true;

	 	return false;
	}

	/**
     * 根據索引訪問數據元素
	 */
	public function find($index)
	{
		if (true === $this->outOfRange($index)) {
			throw new Exception('Index out of range');
		}

		return $this->data[$index];
	}

	/**
	 * 在指定索引 index 處插入數據 data
	 */
	public function insert($index, $data)
	{
		if (true === $this->full()) {
			throw new Exception('Array is full');
		}

		for ($i = $this->len - 1; $i >= $index; $i--) {
			$this->data[$i] = $this->data[$i - 1];
		}
		$this->data[$index] = $data;
		$this->len++;

		return $index;
	}

	/**
     * 刪除指定索引的值
	 */
	public function delete($index)
	{
		if (true === $this->outOfRange($index)) {
			throw new Exception('Index out of range');
		}
		
		$data = $this->data[$index];
		for ($i = $index; $i < $this->len - 1; $i++) {
			$this->data[$i] = $this->data[$i + 1];
		}
		// unset 掉移動元素後最後的重複元素
		unset($this->data[$this->len - 1]);
		$this->len--;

		return $data;
	}
}

鏈表的基本操作

  • 初始化鏈表
  • 插入一個節點
  • 刪除指定節點
  • 查詢值等於給定值的節點

鏈表的代碼實現 (PHP)

class LinkedListNode
{
	// 節點的數據
	public $data;
	// 節點的指針
	public $next;

	public function __construct($data = null)
	{
		$this->data = $data;
		$this->next = null;
	}
}

class LinkedList
{
	/**
	 * 哨兵,頭節點
	 * @var LinkedListNode
	 */
	public $head;
	// 鏈表的長度
	public $len;

	/**
	 * 初始化鏈表
	 */
	public function __construct(LinkedListNode $head)
	{
		$this->head = $head;
		$this->len = 0;
	}
	
	/**
	 * 插入節點,默認頭插法 (頭節點後插入)
	 */
	public function insert($value)
	{
		try {
			$this->insertAfterNode($this->head, $value)
		} catch (Exception $e) {
			throw new Exception($e);
		}
		
		return true;
	}

	/**
	 * 查詢值等於給定值的節點
	 */
	public function getNodeByValue($value)
	{
		$curNode = $this->head;
		while(null !== $curNode) {
			if ($value == $curNode->data) {
				return $curNode;
			}
			$curNode = $curNode->next;
		}
		
		return null;
	}

	/**
	 * 查詢鏈表的第 index 個節點
	 */
	public function getNodeByIndex($index)
	{
		if ($index <= 0 || $index > $this->len) {
			throw new Exception('Index out of range');
		}
		
		$curNode = $this->head;
		for ($i = 0; $i <= $index; $i++) {
			$curNode = $curNode->next;
		}

		return $curNode;
	}

	public function delete(LinkedListNode $node)
	{
		if (null === $node) {
			throw new Exception('Invalid node');
		}
		
		$preNode = $this->getPreNode($node);
		$preNode->next = $node->next;
		unset($node);
		$this->len--;

		return true;
	}
	
	private function getPreNode(LinkedListNode $node)
	{
		if (null === $node) {
			throw new Exception('Invalid node');
		}

		$curNode = $this->head;
		$preNode = $this->head;
		while (null != $curNode && $curNode != $node) {
			$preNode = $curNode;
			$curNode = $curNode->next;
		}
		
		return $preNode;
	}

	/**
     * 指定節點後插入元素
	 */
	private function insertAfterNode(LinkedListNode $node, $value)
	{
		if (null === $node) throw new Exception('Node is null');
		
		$newNode = new LinkedListNode($value);
		$newNode->next = $node->next;
		$node->next = $newNode;
		$this->len++;

		return true;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章