以下給出幾種簡單的廣義表模型:
由上圖我們可以看到,廣義表的節點型別無非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 廣義表的儲存 現在我們來實現簡單廣義表的儲存,允許表中的元素是字母或者數字。由於廣義表中的元素有可能是...