C 如何實現廣義表詳解

2022-10-04 01:39:06 字數 3778 閱讀 8338

以下給出幾種簡單的廣義表模型:

由上圖我們可以看到,廣義表的節點型別無非head、value、sub三種,這裡設定列舉型別,利用列舉變數來記錄每個節點的型別:

enum type

;每個節點都有自己的型別以及next指標,除此之外,如果該節點是value型別還要分配空間儲存該節點的有效值;但是若該節點是sub型別,就需定義乙個指標指向子表的頭。

這裡我們可以用聯合來解決這個問題。

(聯合(或共同體)是一種不同資料型別成員之間共享儲存空間的方法,並且聯合體物件在同一時間只能儲存乙個成員值)

構造節點:

struct generalizednode

;

generalizednode(type type = head, char value = '0')

:_value(value)

,_type(type)

, _next(null)}};

廣義表的定義及基本操作: 

class generalized

;初始化建立廣義表進行迴圈遞迴。遍歷字串時遇到字元就建立值節點,遇到'('就進行遞迴並建立子表;遇到')'就結束當前子表的建立,並返回當前子表的頭指標。 

generalizednode* _creatlist(const char*& str)

else if (*str == '(')

else if (*str == ')')

str++;

} return head;

}列印廣義表:當節點的型別為sub時進行遞迴,最後不要忘了每列印完一層要列印乙個後括號。

void _print(generalizednode* head)

generalizednode* cur = head;

while (cur)

else if (cur->_type == value)

}else if (cur->_type == sub)

}cur = cur->_next;

} cout << ')';

}獲取值節點的個數:設定count變數,遇到值節點就加1,遇到sub節點進www.cppcns.com行遞迴並將返回值加給count

size_t _amount(generalizednode* head)

if (begin->_type == sub)

begin = begin->_next;

} return count;

}廣義表的深度:設定變數dp和max分別用來記錄當前子表即當前sub節點指向的子表深度,以及本層所有的sub節點中深度最大的子表的深度。

size_t _depth(generalizednode* head)

size_t dp=0;

generalizednode* cur = head;

size_t max = 0;

while (cur)

}cur = cur->_next;

} return max+1;

}銷毀廣義表:依次遍歷節點,遇到子表遞迴,將子表的節點delete完成後,再回到當前層繼續遍歷。

void _destory(generalizednode* head)

while (head)

delete head;

head = begin;

}}例項演示

定義:廣義表是n(n≥0)個元素a1,a2,…,ai,…,an的有限序列。

其中:①ai--或者是原子或者是乙個廣義表。

②廣義表通常記作:

ls=( a1,a2,…,ai,…,an)。

③ls是廣義表的名字,n為它的長度。

④若ai是廣義表,則稱它為ls的子表。

注意:①廣義表通常用圓括號括起來,用逗號分隔其中的元素。

②為了區分原子和廣義表,書寫時用大寫字母表示廣義表,用小寫字母表示原子。

③若廣義表ls非空(n≥1),則al是ls的表頭,其餘元素組成的表(a1,a2,…,an)稱為ls的表尾。

④廣義表是遞迴定義的

畫圖舉例:

**實現:

[cpp] view plain copy

#include

using namespace std;

//表示廣義表的結點型別

enum nodetype ;

//表示廣義表結點的結構體

str generalistnode ;

generalistnode(nodetype type = head_type, char value = '\0')

:_type(type)

,_next(null)

else if(type == sub_type)

} };

class generalist

~generalist()

{} public:

void print();//對外提供的列印廣義表的介面

int size();//廣義表中值結點的數目的對外獲取介面

int depth();//廣義表的最深層次的對外獲取介面

private:

void _creategeneralist(generalistnode *& link, const char *& str);

bool _isvalue(const char ch);//判斷指定字元是否為值結點所允許的型別

int _size(generalistnode *head);//計算廣義表中值結點的數目的實現

int _depth(generalistnode *head);//計算廣義表的最深層次的實現

void _print(generalistnode *link);//列印廣義表的介面的底層實現

};

//建立廣義表

void generalist::_creategeneralist(generalistnode *& link, const char *& str)

else if(*str == '(')else if(*str == ')')else

} }

int generalist::size()

//計算廣義錶值結點的個數

int generalist::_size(generalistnode *head)

else if(cur->_type == sub_type)

cur = cur->_next;

} return size; }

int generalist::depth()

int generalist::_depth(generalistnode *head)

if(depth > maxdepth)

cur = cur->_next;

} return maxdepth; }

void generalist::print()

cout<= 'a' && ch <= 'z' ||

ch >= 'a' && ch <= 'z' ||

ch >= '0' && ch <= '(')

return false;

} 測試**

[cpp] view plain copy

#include"generalist.hpp"

//測試空表

void test1()

{ generalist genlist("()");

genlist.print();

cout<

執行結果

總結

遞迴實現廣義表

廣義表是非線性的結構,是線性表的一種擴充套件,是有n個元素組成有限序列。由於在表的描述中可以巢狀表,允許表中有表,所以可以通過遞迴實現廣義表。具體實現如下 標頭檔案 pragma once 實現廣義表的結構 enum type 列舉型別 struct generalizednode 廣義表的結點 g...

c 之廣義表

廣義表 lists,又稱列表 是一種非線性的資料結構,是線性表的一種推廣。即廣義表中放鬆對錶元素的原子限制,容許它們具有其自身結構。它被廣泛的應用於人工智慧等領域的表處理語言lisp語言中。在lisp語言中,廣義表是一種最基本的資料結構,就連lisp 語言的程式也表示為一系列的廣義表。實現如下 pr...

廣義表的簡單實現

廣義表 廣義表是一種非線性資料結構,是線性表的推廣。廣義表是一種單遞迴的思想,它允許表中有表。例 l 空表,深度為1 l1 具有乙個元素的廣義表,深度為2 l2 a,f b 具有三個元素,深度為3 廣義表的儲存 現在我們來實現簡單廣義表的儲存,允許表中的元素是字母或者數字。由於廣義表中的元素有可能是...