**
廣義表(lists,又稱列表)是線性表的推廣。線性表定義為n>=0個元素a1,a2,a3,…,an的有限序列。線性表的元素僅限於原子項,原子是作為結構上不可分割的成分,它可以是乙個數或乙個結構,若放鬆對錶元素的這種限制,容許它們具有其自身結構,這樣就產生了廣義表的概念。
廣義表是n (n>=0)個元素a1,a2,a3,…,an的有限序列,其中ai或者是原子項,或者是乙個廣義表。通常記作ls=(a1,a2,a3,…,an)。ls是廣義表的名字,n為它的長度。若ai是廣義表,則稱它為ls的子表。
通常用圓括號將廣義表括起來,用逗號分隔其中的元素。為了區別原子和廣義表,書寫時用大寫字母表示廣義表,用小寫字母表示原子。若廣義表ls(n>=1)非空,則a1是ls的表頭,其餘元素組成的表(a2,…an)稱為ls的表尾。
顯然廣義表是遞迴定義的,這是因為在定義廣義表時又用到了廣義表的概念。廣義表的例子如下:
(1)a=()——a是乙個空表,其長度為零。
(2)b=(e)——表b只有乙個原子e,b的長度為1。
(3)c=(a,(b,c,d))——表c的長度為2,兩個元素分別
為原子a和子表(b,c,d)。
(4)d=(a,b,c)——表d的長度為3,三個元素
都是廣義表。顯然,將子表的值代入後,
則有d=(( ),(e),(a,(b,c,d)))。
(5)e=(e)——這是乙個遞迴的表,它的長度為2,e相當於乙個無限的廣義表e=(a,(a,(a,(a,…)))).
從上述定義和例子可推出廣義表的三個重要結論:
(1)廣義表的元素可以是子表,而子表的元素還可以是子表,。由此,廣義表是乙個多層次的結構,可以用圖形象地表示。p108
難以用順序儲存結構(2)廣義錶可為其它表所共享。例如在上述例(4)中,廣義表a,b,c為d的子表,則在d中可以不必列出子表的值,而是通過子表的名稱來引用。
(3)廣義表的遞迴性。
綜上所述,廣義表不僅是線性表的推廣,也是樹的推廣。
由表頭、表尾的定義可知:任何乙個非空廣義表其表頭可能是原子,也可能是列表,而其表尾必定是列表。
gethead(b)=e gettail(b)=( )
gethead(d)=a gettail(d)=(b,c)
由於(b,c)為非空廣義表,則可繼續分解得到:
gethead(b,c)=b gettail(b,c)=(c)
注意廣義表( )和( ( ) )不同。前者是長度為0的空表,
對其不能做求表頭的和表尾的運算;而後者是長度為1的非空表(只不過該表中唯一的乙個元素是空表)。對其可進行分解,得到表頭和表尾均為空表( )。
廣義表的儲存結構
由於廣義表(a1,a2,a3,…an)中的資料元素可以具有不同的結構,(或是原子,或是廣義表),因此,難以用順序儲存結構表示,通常採用鏈式儲存結構,每個資料元素可用乙個結點表示。
由於廣義表中有兩種資料元素,原子或廣義表,因此,需要兩種結構的結點:一種是表結點,用以表示列表;一種是原子結點,用以表示原子。
若列表不空,則可分解成表頭和表尾;反之,一對確定的表頭和表尾可唯一確定列表。由此,乙個表結點可由三個域組成:標誌域、指示表頭的指標域和指示表尾的指標域;而原子結點只需兩個域:標誌域和值域。
1、僅有表結點由三個域組成:
標誌域、指示表頭的指標域和指示表尾的指標域;而原子域只需兩個域:標誌域和值域。
頭尾鍊錶儲存表示
[cpp]view plain
copy
print?
typedef enum elemtag; //atom==0:表示原子,list==1:表示子表
typedef struct glnode ptr;
// ptr是表結點的指標域,ptr.hp 和ptr.tp分別指向表頭和表尾
};
} *glist; //廣義表型別
typedef enum elemtag; //atom==0:表示原子,list==1:表示子表typedef struct glnode ptr; // ptr是表結點的指標域,ptr.hp 和ptr.tp分別指向表頭和表尾 };} *glist; //廣義表型別示例如圖:
這種儲存結構的三個特點:
1。除空表的表頭指標為空外,對任何非空列表,其表頭指標均指向乙個表結點,且該結點中的hp域指示列表表頭,tp域指向列表表尾(除非表尾為空,則指標為空,否則必為表結點);
2。容易分清列表中原子和子表所在層次。如在列表d中,原子e和a在同一層次上,而b、c和d在同一層次且比e和a低一層,b和c是同一層的子表;
3。最高層的表結點個數即為列表的長度。
2、表結點和原子結點均由三個域組成:標誌域、指示表頭的指標域和指示表尾的指標域;原子結點的三個域為:標誌域、值域和指示表尾的指標域。
其型別定義如下:
擴充套件線性鍊錶儲存表示
[cpp]view plain
copy
print?
typedef enum elemtag;
//atom==0:表示原子,list==1:表示子表
typedef struct glnode ;
struct glnode *tp;
//相當於線性鍊錶的next,指向下乙個元素結點
} *glist; //廣義表型別glist 是一種擴充套件的線性鍊錶
typedef enum elemtag; //atom==0:表示原子,list==1:表示子表typedef struct glnode ; struct glnode *tp; //相當於線性鍊錶的next,指向下乙個元素結點} *glist; //廣義表型別glist 是一種擴充套件的線性鍊錶示例如圖:
注意:
(1)若廣義表ls非空(n≥1),則al是ls的表頭,其餘元素組成的表(a2,a2,…,an)稱為ls的表尾。所以
取廣義表的表尾是取除表頭外的後面元素。
(2)若乙個廣義表的表頭為空表,則此廣義表亦為空表是錯的
廣義表的建立及求其深度
include include include typedef enumelemtag struct node struct node tail char a 100 int len,time int max 0 struct node dfs int step t struct node mall...
廣義表演算法庫及應用
問題描述 1 建立廣義表演算法庫,包括 頭文glist.h,定義資料型別,宣告函式 原始檔glist.cpp,實現廣義表的基本運算,主要演算法包括 int gllength glnode g 求廣義表g的長度 int gldepth glnode g 求廣義表g的深度 glnode creategl...
廣義表的建立
include include include define error 1 define over flow 0 define ok 1 define max str len 100 char hstr max str len char istr max str len typedef int s...