鍍金池/ 教程/ Java/ LISP - 樹(shù)
LISP - 樹(shù)
LISP - 錯(cuò)誤處理
LISP - 謂詞
LISP - 決策
LISP - 變量
LISP - 數(shù)組
LISP - 對(duì)象系統(tǒng)(CLOS)
LISP - 輸入和輸出
Lisp教程
LISP - 數(shù)字
LISP - 循環(huán)
LISP - 常量
LISP - 集合
LISP - 字符
LISP - 程序結(jié)構(gòu)
LISP - 文件I/O
LISP - 哈希表
LISP - 宏
LISP - 數(shù)據(jù)類(lèi)型
LISP - 包
LISP - 符號(hào)
LISP - 運(yùn)算符
LISP - 基本語(yǔ)法
LISP - 函數(shù)
LISP - 向量
LISP - 結(jié)構(gòu)
LISP - 概述介紹

LISP - 樹(shù)

可以從cons單元構(gòu)建樹(shù)的數(shù)據(jù)結(jié)構(gòu),如清單列表。

為了實(shí)現(xiàn)樹(shù)形結(jié)構(gòu),則必須設(shè)計(jì)功能,將遍歷cons 單元,在特定的順序,例如,前序,順序和后序的二進(jìn)制樹(shù)。

樹(shù)列表的列表

讓我們考慮由cons單元的樹(shù)狀結(jié)構(gòu),形成列出的清單如下:

((1 2) (3 4) (5 6)).

圖解,它可以表示為:

treestructure

LISP樹(shù)的功能

雖然多數(shù)時(shí)候仍需要根據(jù)其它特殊需求編寫(xiě)自己的樹(shù)的功能,LISP提供了一些樹(shù)的功能,您可以使用。

除了所有列表函數(shù),以下是工作在樹(shù)結(jié)構(gòu)函數(shù):

函數(shù) 描述
copy-tree x &optional vecp 它返回cons單元×樹(shù)的副本。它遞歸地拷貝兩款車(chē)和cdr方向。如果x不是一個(gè)cons單元,該函數(shù)只返回x不變。如果可選vecp參數(shù)為true,這個(gè)函數(shù)將向量(遞歸),以及cons單元。
tree-equal x y &key :test :test-not :key 它比較兩棵樹(shù)的cons單元。如果x和y是兩個(gè)cons單元,他們的汽車(chē)和cdr是遞歸比較。如果x和y都不是一個(gè)cons單元,它們是由eql比較,或根據(jù)指定的測(cè)試。:key函數(shù),如果指定,應(yīng)用到這兩個(gè)目錄樹(shù)中的元素。
subst new old tree &key :test :test-not :key 它可以代替出現(xiàn)給老項(xiàng)與新項(xiàng),在樹(shù),這是cons單元的一棵樹(shù)。
nsubst new old tree &key :test :test-not :key 它的工作原理與subst相同,但它破壞了原來(lái)的樹(shù)。
sublis alist tree &key :test :test-not :key 它的工作原理就像subst,只不過(guò)它采用的新舊對(duì)關(guān)聯(lián)表alist。樹(shù)(應(yīng)用后:key函數(shù),如果有的話)中的每個(gè)元素,與alist的車(chē)相比;如果它匹配,它被替換為相應(yīng)的cdr。
nsublis alist tree &key :test :test-not :key 它的工作原理與sublis相同,而是一個(gè)破壞性的版本。

示例 1

創(chuàng)建一個(gè)名為main.lisp一個(gè)新的源代碼文件,并在其中輸入如下代碼:

(setq lst (list '(1 2) '(3 4) '(5 6)))
(setq mylst (copy-list lst))
(setq tr (copy-tree lst))
(write lst)
(terpri)
(write mylst)
(terpri)
(write tr)

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

((1 2) (3 4) (5 6))
((1 2) (3 4) (5 6))
((1 2) (3 4) (5 6))

示例 2

創(chuàng)建一個(gè)名為main.lisp一個(gè)新的源代碼文件,并在其中輸入如下代碼:

(setq tr '((1 2 (3 4 5) ((7 8) (7 8 9)))))
(write tr)
(setq trs (subst 7 1 tr))
(terpri)
(write trs)

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

((1 2 (3 4 5) ((7 8) (7 8 9))))
((7 2 (3 4 5) ((7 8) (7 8 9))))

建立自己的樹(shù)

讓我們嘗試建立自己的樹(shù),使用LISP列表功能。

首先,讓我們創(chuàng)建一個(gè)包含一些數(shù)據(jù)的新節(jié)點(diǎn):

(defun make-tree (item)
  "it creates a new node with item."
  (cons (cons item nil) nil))

接下來(lái)讓我們添加一個(gè)子節(jié)點(diǎn)插入到樹(shù):它會(huì)采取兩種樹(shù)節(jié)點(diǎn),并添加第二棵樹(shù)作為第一個(gè)的子樹(shù)。

(defun add-child (tree child)
  (setf (car tree) (append (car tree) child))
  tree)

接下來(lái)讓我們添加一個(gè)子節(jié)點(diǎn)插入到樹(shù):這將需要一個(gè)樹(shù)節(jié)點(diǎn),并返回該節(jié)點(diǎn)第一個(gè)子節(jié)點(diǎn),或nil,如果這個(gè)節(jié)點(diǎn)沒(méi)有任何子節(jié)點(diǎn)。

(defun first-child (tree)
  (if (null tree)
    nil
    (cdr (car tree))))

這個(gè)函數(shù)會(huì)返回一個(gè)給定節(jié)點(diǎn)的下一個(gè)同級(jí)節(jié)點(diǎn):它需要一個(gè)樹(shù)節(jié)點(diǎn)作為參數(shù),并返回一個(gè)指向下一個(gè)同級(jí)節(jié)點(diǎn),或者為nil,如果該節(jié)點(diǎn)沒(méi)有任何。

(defun next-sibling (tree)
   (cdr tree))

最后,我們需要一個(gè)函數(shù)來(lái)返回一個(gè)節(jié)點(diǎn)的信息:

(defun data (tree)
  (car (car tree)))

示例

本示例使用上述功能:

創(chuàng)建一個(gè)名為main.lisp一個(gè)新的源代碼文件,并在其中輸入如下代碼:

(defun make-tree (item)
  "it creates a new node with item."
  (cons (cons item nil) nil))
 (defun first-child (tree)
  (if (null tree)
    nil
    (cdr (car tree))))
 (defun next-sibling (tree)
   (cdr tree))
(defun data (tree)
   (car (car tree)))
 (defun add-child (tree child)
  (setf (car tree) (append (car tree) child))
  tree)

(setq tr '((1 2 (3 4 5) ((7 8) (7 8 9)))))
(setq mytree (make-tree 10))
(write (data mytree))
(terpri)
(write (first-child tr))
(terpri)
(setq newtree (add-child tr mytree))
(terpri)
(write newtree)

當(dāng)執(zhí)行代碼,它返回以下結(jié)果:

10
(2 (3 4 5) 
            
上一篇:LISP - 宏下一篇:Lisp教程