1. 程式人生 > >​​​​​​​ 學習資料結構的好資料

​​​​​​​ 學習資料結構的好資料

學習資料結構的好資料

第一章 概  論

1.資料:資訊的載體,能被計算機識別、儲存和加工處理。

2.資料元素:資料的基本單位,可由若干個資料項組成,資料項是具有獨立含義的最小標識單位。

3.資料結構:資料之間的相互關係,即資料的組織形式。 它包括:1)資料的邏輯結構,從邏輯關係上描述資料,與資料儲存無關,獨立於計算機; 2)資料的儲存結構,是邏輯結構用計算機語言的實現,依賴於計算機語言。 3)資料的運算,定義在邏輯結構上,每種邏輯結構都有一個運算集合。常用的運算:檢索/插入/刪除/更新/排序。

4.資料的邏輯結構可以看作是從具體問題抽象出來的數學模型。資料的儲存結構是邏輯結構用計算機語言的實現。

5.資料型別:一個值的集合及在值上定義的一組操作的總稱。分為:原子型別和結構型別。

6.抽象資料型別:抽象資料的組織和與之相關的操作。優點:將資料和操作封裝在一起實現了資訊隱藏。

7. 抽象資料型別ADT:是在概念層上描述問題;類:是在實現層上描述問題;在應用層上操作物件(類的例項)解決問題。

8.資料的邏輯結構,簡稱為資料結構,有: (1)線性結構,若結構是非空集則僅有一個開始和終端結點,並且所有結點最多隻有一個直接前趨和後繼。 (2)非線性結構,一個結點可能有多個直接前趨和後繼。

9.資料的儲存結構有: 1)順序儲存,把邏輯相鄰的結點儲存在物理上相鄰的儲存單元內。 2)連結儲存,結點間的邏輯關係由附加指標欄位表示。 3)索引儲存,儲存結點資訊的同時,建立附加索引表,有稠密索引和稀疏索引。 4)雜湊儲存,按結點的關鍵字直接計算出儲存地址。

10.評價演算法的好壞是:演算法是正確的;執行演算法所耗的時間;執行演算法的儲存空間(輔助儲存空間);易於理解、編碼、除錯。

11.演算法的時間複雜度T(n):是該演算法的時間耗費,是求解問題規模n的函式。記為O(n)。 時間複雜度按數量級遞增排列依次為:常數階O(1)、對數階O(log2n)、線性階O(n)、線性對數階O(nlog2n)、平方階O(n^2)、立方階O(n^3)、……k次方階O(n^k)、指數階O(2^n)。13.演算法的空間複雜度S(n):是該演算法的空間耗費,是求解問題規模n的函式。

12.演算法衡量:是用時間複雜度和空間複雜度來衡量的,它們合稱演算法的複雜度。 13. 演算法中語句的頻度不僅與問題規模有關,還與輸入例項中各元素的取值相關。   第 二 章   線 性 表   1.線性表:是由n(n≥0)個數據元素組成的有限序列。

2.線性表的基本運算有: 1)InitList(L),構造空表,即表的初始化; 2)ListLength(L),求表的結點個數,即表長; 3)GetNode(L,i),取表中第i個結點,要求1≤i≤ListLength(L); 4)LocateNode(L,x)查詢L中值為x的結點並返回結點在L中的位置,有多個x則返回首個,沒有則返回特殊值表示查詢失敗。 5)InsertList(L,x,i)在表的第i個位置插入值為x的新結點,要求1≤i≤ListLength(L)+1; 6)DeleteList(L,i)刪除表的第i個位置的結點,要求1≤i≤ListLength(L);

3.順序表:把線性表的結點按邏輯次序存放在一組地址連續的儲存單元裡。

4.順序表結點的儲存地址計算公式:Loc(ai)=Loc(a1)+(i-1)*C;1≤i≤n

5.順序表上的基本運算   (1)插入 void insertlist(seqlist *L,datatype x,int i) {  int j;  if(i<1||i>L->length+1)   error(“position error”);  if(L->length>=listsize)   error(“overflow”);  for(j=L->length-1;j>=i-1;j--)   L->data[j+1]=L->data[j];  結點後移  L->data[i-1]=x;  L->length++; } 在順序表上插入要移動表的n/2結點,演算法的平均時間複雜度為O(n)。 (2)刪除 void delete (seqlist *L,int i) {  int j;  if(i<1||i>L->length)   error(“position error”);  for(j=i;j<=L->length-1;j++)   L->data[j-1]=L->data[j];  結點前移   L->length--; } 在順序表上刪除要移動表的(n+1)/2結點,演算法的平均時間複雜度為O(n)。

6.單鏈表:只有一個鏈域的連結串列稱單鏈表。 在結點中儲存結點值和結點的後繼結點的地址,data  next  data是資料域,next是指標域。  (1)建立單鏈表。時間複雜度為O(n)。 加頭結點的優點:1)連結串列第一個位置的操作無需特殊處理;2)將空表和非空表的處理統一。 (2)查詢運算。時間複雜度為O(n)。  1) 按序號查詢。 Listnode * getnode(linklist head,int i) {  int j;  listnode *p;  p=head;j=0;  while(p->next&&j<i){   p=p->next; 指標下移   j++;  }  if(i==j)   return p;  else   return NULL; } 2) 按值查詢。 Listnode * locatenode(linklist head ,datatype key) {  listnode *p=head->next;  while(p&&p->data!=key)   p=p->next;  return p; } (3)插入運算。時間複雜度為O(n)。 Void insertlist(linklist head ,datatype x, int i) {  listnode *p;  p=getnode(head,i-1);  if(p==NULL);   error(“position error”);  s=(listnode *)malloc(sizeof(listnode));  s->data=x;  s->next=p->next;  p->next=s;  } (4) 刪除運算。時間複雜度為O(n)。 Void deletelist(linklist head ,int i) {  listnode *p ,*r;  p=getnode(head ,i-1);  if(p==NULL||p->next==NULL)   error(“position error”);  r=p->next;  p->next=r->next;  free(r); }

7.迴圈連結串列:是一種首尾相連的連結串列。特點是無需增加儲存量,僅對錶的連結方式修改使表的處理靈活方便。 8.空迴圈連結串列僅由一個自成迴圈的頭結點表示。 9.很多時候表的操作是在表的首尾位置上進行,此時頭指標表示的單迴圈連結串列就顯的不夠方便,改用尾指標rear來表示單迴圈連結串列。用頭指標表示的單迴圈連結串列查詢開始結點的時間是O(1),查詢尾結點的時間是O(n);用尾指標表示的單迴圈連結串列查詢開始結點和尾結點的時間都是O(1)。

10.在結點中增加一個指標域,prior|data|next。形成的連結串列中有兩條不同方向的鏈稱為雙鏈表。 1) 雙鏈表的前插操作。時間複雜度為O(1)。 Void dinsertbefore(dlistnode *p ,datatype x) {  dlistnode *s=malloc(sizeof(dlistnode));  s->data=x;  s->prior=p->prior;  s->next=p;  p->prior->next=s;  p->prior=s; } 2) 雙鏈表的刪除操作。時間複雜度為O(1)。 Void ddeletenode(dlistnode *p) {  p->prior->next=p->next;  p->next->prior=p->prior;  free(p); }

11.順序表和連結串列的比較 1) 基於空間的考慮:順序表的儲存空間是靜態分配的,連結串列的儲存空間是動態分配的。順序表的儲存密度比連結串列大。因此,線上性表長度變化不大,易於事先確定時,宜採用順序表作為儲存結構。 2) 基於時間的考慮:順序表是隨機存取結構,若線性表的操作主要是查詢,很少有插入、刪除操作時,宜用順序表結構。對頻繁進行插入、刪除操作的線性表宜採用連結串列。若操作主要發生在表的首尾時採用尾指標表示的單迴圈連結串列。

12.儲存密度=(結點資料本身所佔的儲存量)/(整個結點結構所佔的儲存總量) 儲存密度:順序表=1,連結串列<1。 第 三 章   棧 和 隊 列    1.棧是限制僅在表的一端進行插入和刪除運算的線性表又稱為後進先出表(LIFO表)。插入、刪除端稱為棧頂,另一端稱棧底。表中無元素稱空棧。

2.棧的基本運算有: 1) initstack(s),構造一個空棧; 2) stackempty(s),判棧空; 3) stackfull(s),判棧滿; 4) push(s,x),進棧; 5) pop (s),退棧; 6) stacktop(s),取棧頂元素。

3.順序棧:棧的順序儲存結構稱順序棧。

4.當棧滿時,做進棧運算必定產生空間溢位,稱“上溢”。 當棧空時,做退棧運算必定產生空間溢位,稱“下溢”。上溢是一種錯誤應設法避免,下溢常用作程式控制轉移的條件。

5.在順序棧上的基本運算: 1) 置空棧。 Void initstack(seqstack *s) {  s->top=-1; } 2)判棧空。 int stackempty(seqstack *s) {  return s->top==-1; } 3)判棧滿。 int stackfull(seqstack *s) {  return s->top==stacksize-1; } 4)進棧。 Void push(seqstack *s,datatype x) {  if(stackfull(s))   error(“stack overflow”);  s->data[++s->top]=x; } 5)退棧。 Datatype pop(seqstack *s) {  if(stackempty(s))   error(“stack underflow”);  return S->data[s->top--]; } 6)取棧頂元素。 Dtatatype stacktop(seqstack *s) {  if(stackempty(s))   error(“stack underflow”);  return S->data[s->top]; }

6.鏈棧:棧的鏈式儲存結構稱鏈棧。棧頂指標是連結串列的頭指標。

7.鏈棧上的基本運算: 1) 建棧。 Void initstack(linkstack *s) {  s->top=NULL; } 2)判棧空。 Int stackempty (linkstack *s) {  return s->top==NULL; } 3) 進棧。 Void push(linkstack *s,datatype x) {  stacknode *p=(stacknode *)malloc(sizeof(stacknode));  p->data=x;  p->next=s->top;  s->top=p; } 4) 退棧。 Datatype pop(linksatck *s) {  datatype x;  stacknode *p=s->top;  if(stackempty(s))   error(“stack underflow”);  x=p->data;  s->top=p->next;  free(p);  return x; } 5) 取棧頂元素。 Datatype stacktop(linkstack *s) {  if(stackempty(s))   error(“stack is empty”);  return s->top->data; }   8.佇列是一種運算受限的線性表,允許刪除的一端稱隊首,允許插入的一端稱隊尾。佇列又稱為先進先出線性表,FIFO表。

9.佇列的基本運算: 1) initqueue(q),置空隊; 2) queueempty(q),判隊空; 3) queuefull(q),判隊滿; 4) enqueue(q,x),入隊; 5) dequeue(q),出隊; 6) queuefront(q),返回隊頭元素。

10.順序佇列:佇列的順序儲存結構稱順序佇列。設定front和rear指標表示隊頭和隊尾元素在向量空間的位置。

11.順序佇列中存在“假上溢”現象,由於入隊和出隊操作使頭尾指標只增不減導致被刪元素的空間無法利用,隊尾指標超過向量空間的上界而不能入隊。

12.為克服“假上溢”現象,將向量空間想象為首尾相連的迴圈向量,儲存在其中的佇列稱迴圈佇列。i=(i+1)%queuesize

13.迴圈佇列的邊界條件處理:由於無法用front==rear來判斷佇列的“空”和“滿”。 解決的方法有: 1) 另設一個布林變數以區別佇列的空和滿; 2) 少用一個元素,在入隊前測試rear在迴圈意義下加1是否等於front; 3) 使用一個記數器記錄元素總數。

14.迴圈佇列的基本運算: 1) 置隊空。 Void initqueue(cirqueue *q) {  q->front=q->rear=0;  q->count=0; } 2) 判隊空。 Int queueempty(cirqueue *q) {  return q->count==0; } 3) 判隊滿。 Int queuefull(cirqueue *q) {  return q->count==queuesize; } 4) 入隊。 Void enqueue(cirqueue *q ,datatype x) {  if(queuefull(q))   error(“queue overfolw”);  q->count++;  q->data[q->rear]=x;  q->rear=(q->rear+1)%queuesize; } 5) 出隊。 Datatype dequeue(cirqueue *q) {  datatype temp;  if(queueempty(q))   error(“queue underflow”);  temp=q->data[q->front];  q->count--;  q->front=(q->front+1)%queuesize;  return temp; } 6) 取隊頭元素。 Datatype queuefront(cirqueue *q) {  if(queueempty(q))   error(“queue is empty”);  return q->data[q->front]; }

15.鏈佇列:佇列的鏈式儲存結構稱鏈佇列,鏈佇列由一個頭指標和一個尾指標唯一確定。

16.鏈佇列的基本運算: 1) 建空隊。 Void initqueue(linkqueue *q) {  q->front=q->rear=NULL; } 2) 判隊空。 Int queueempty(linkqueue *q) {  return q->front==NULL&&q->rear==NULL; } 3) 入隊。 Void enqueue(linkqueue *q,datatype x) {  queuenode *p=(queuenode *)malloc(sizeof(queuenode));  p->data=x;  p->next=NULL;  if(queueempty(q))   q-front=q->rear=p;  else{   q->rear->next=p;   q->rear=p;   } } 4) 出隊。 Datatype dequeue(linkqueue *q) {  datatype x;  queuenode *p;  if(queueempty(q))   error(“queue is underflow”);  p=q->front;  x=p->data;  q->front=p->next;  if(q->rear==p) q->rear=NULL;  free(p);  return x; } 5) 取隊頭元素。 Datatype queuefront(linkqueue *q) {  if(queueempty(q))   error(“queue is empty”);  return q->front->data; }

  第 四 章   串   1.串:是由零個或多個字元組成的有限序列;包含字元的個數稱串的長度; 2.空串:長度為零的串稱空串;     空白串:由一個或多個空格組成的串稱空白串; 子串:串中任意個連續字元組成的子序列稱該串的子串;    主串:包含子串的串稱主串; 子串的首字元在主串中首次出現的位置定義為子串在主串中的位置; 3.空串是任意串的子串;  任意串是自身的子串; 串常量在程式中只能引用但不能改變其值; 串變數取值可以改變; 4.串的基本運算 1) int strlen(char *s);求串長。 2) char *strcpy(char * to,char * from);串複製。 3) char *strcat(char * to,char * from);串聯接。 4) int strcmp(char *s1,char *s2);串比較。 5) char *strchr(char *s,char c);字元定位。 5.串的儲存結構: (1)串的順序儲存:串的順序儲存結構稱順序串。按儲存分配不同分為: 1) 靜態儲存分配的順序串: 直接用定長的字元陣列定義,以“\0”表示串值終結。 #define maxstrsize 256 typedef char seqstring[maxstrsize]; seqstring s; 不設終結符,用串長表示。 Typedef struct{  Char ch[maxstrsize];  Int length; }seqstring; 以上方式的缺點是:串值空間大小是靜態的,難以適應插入、連結等操作。 2) 動態儲存分配的順序串: 簡單定義:typedef char * string; 複雜定義:typedef struct{    char *ch;    int length;   }hstring; (2)串的鏈式儲存:串的鏈式儲存結構稱鏈串。鏈串由頭指標唯一確定。型別定義: typedef struct node{  char data;  struct node *next; }linkstrnode; typedef linkstrnode *linkstring; linkstring s; 將結點資料域存放的字元個數定義為結點的大小。結點大小不為1的鏈串型別定義: #define nodesize 80 typedef struct node{  char data[nodesize];  struct node * next; }linkstrnode; 6.串運算的實現 (1)順序串上的子串定位運算。 1)子串定位運算又稱串的模式匹配或串匹配。主串稱目標串;子串稱模式串。 2)樸素的串匹配演算法。時間複雜度為O(n^2)。比較的字元總次數為(n-m+1)m。 Int naivestrmatch(seqstring t,seqstring p) {  int i,j,k;  int m=p.length;  int n=t.length;  for(i=0;i<=n-m;i++){   j=0;k=i;   while(j<m&&t.ch[k]==p.ch[j]){    j++;k++;   }   if (j==m) return i;  }  return –1; } (2)鏈串上的子串定位運算。時間複雜度為O(n^2)。比較的字元總次數為(n-m+1)m。 Linkstrnode * lilnkstrmatch(linkstring T, linkstring P) {  linkstrnode *shift, *t, *p;  shift=T;  t=shift;p=P;  while(t&&p){   if(t->data==p->data){ t=t->next;    p=p->next;    }   else{    shift=shift->next;    t=shift;    p=P;    }  }  if(p==NULL)   return shift;  else   return NULL; }   第 五 章    多 維 數 組 和 廣 義 表

1.多維陣列:一般用順序儲存的方式表示陣列。

2.常用方式有:1)行優先順序,將陣列元素按行向量排列; 2)列優先順序,將陣列元素按列向量排列。

3.計算地址的函式:LOC(Aij)=LOC(Ac1c2)+((i-c1)*(d2-c2+1)+j-c2)*d

4.矩陣的壓縮儲存:為多個非零元素分配一個儲存空間;對零元素不分配儲存空間。

(1) 對稱矩陣:在一個n階的方陣A中,元素滿足Aij=Aji 0<=i,j<=n-1;稱為對稱矩陣。 元素的總數為:n(n+1)/2; 設:I=i或j中大的一個數;J=i或j中小的一個數; 則:k=I*(I+1)/2+J; 地址計算:LOC(Aij)=LOC(sa[k])=LOC(sa[0])+k*d= LOC(sa[0])+ (I*(I+1)/2+J )*d

(2)三角矩陣:以主對角線劃分,三角矩陣有上三角和下三角;上三角的主對角線下元素均為常數c;下三角的主對角線上元素均為常數c。 元素總數為:(n(n+1)/2)+1; 以行優先順序存放的Aij與SA[k]的關係: 上三角陣:k=i*(2n-i+1)/2+j-i; 下三角陣:k=i*(i+1)/2+j;

(3)對角矩陣:所有的非零元素集中在以主對角線為中心的帶狀區域,相鄰兩側元素均為零。|i-j|>(k-1)/2 以行優先順序存放的Aij與SA[k]的關係:k=2i+j;

5.稀疏矩陣:當矩陣A中有非零元素S個,且S遠小於元素總數時,稱為稀疏矩陣。 對其壓縮的方法有順序儲存和鏈式儲存。

(1)三元組表:將表示稀疏矩陣的非零元素的三元組(行號、列號、值)按行或列優先的順序排列得到的一個結點均是三元組的線性表,將該表的線性儲存結構稱為三元組表。其型別定義: #define maxsize 10000 typedef int datatype; typedef struct{  int i,j;  datatype v; }trituplenode; typedef struct{  trituplenode data[maxsize];  int m,n,t; }tritupletable;

(2)帶行表的三元組表:在按行優先儲存的三元組表中加入一個行表記錄每行的非零元素在三元組表中的起始位置。型別定義: #define maxrow 100 typedef struct{  tritulpenode data[maxsize];  int rowtab[maxrow];  int m, n, t; }rtritulpetable;   6.廣義表:是線性表的推廣,廣義表是n個元素的有限序列,元素可以是原子或一個廣義表,記為LS。

7.若元素是廣義表稱它為LS的子表。若廣義表非空,則第一個元素稱表頭,其餘元素稱表尾。

8.表的深度是指表展開後所含括號的層數。

9.把與樹對應的廣義表稱為純表,它限制了表中成分的共享和遞迴;

10.允許結點共享的表稱為再入表;

11.允許遞迴的表稱為遞迴表;

12.相互關係:線性表∈純表∈再入表∈遞迴表;

13.廣義表的特殊運算:1)取表頭head(LS);2)取表尾tail(LS);   第 六 章   樹

1.樹:是n個結點的有限集T,T為空時稱空樹,否則滿足: 1)有且僅有一個特定的稱為根的結點; 2)其餘結點可分為m個互不相交的子集,每個子集本身是一棵樹,並稱為根的子樹。 2.樹的表示方法:1)樹形表示法;2)巢狀集合表示法;3)凹入表表示法;4)廣義表表示法; 3.一個結點擁有的子樹數稱為該結點的度;一棵樹的度是指樹中結點最大的度數。 4.度為零的結點稱葉子或終端結點;度不為零的結點稱分支結點或非終端結點 5.根結點稱開始結點,根結點外的分支結點稱內部結點; 6.樹中某結點的子樹根稱該結點的孩子;該結點稱為孩子的雙親; 7.樹中存在一個結點序列K1,K2,…Kn,使Ki為Ki+1的雙親,則稱該結點序列為K1到Kn的路徑或道路; 8.樹中結點K到Ks間存在一條路徑,則稱K是Ks的祖先,Ks是K的子孫; 9.結點的層數從根算起,若根的層數為1,則其餘結點層數是其雙親結點層數加1;雙親在同一層的結點互為堂兄弟;樹中結點最大層數稱為樹的高度或深度; 10.樹中每個結點的各個子樹從左到右有次序的稱有序樹,否則稱無序樹; 11.森林是m棵互不相交的樹的集合。    12.二叉樹:是n個結點的有限集,它或為空集,或由一個根結點及兩棵互不相交的、分別稱為該根的左子樹和右子樹的二叉樹組成。 13.二叉樹不是樹的特殊情況,這是兩種不同的資料結構;它與無序樹和度為2的有序樹不同。 14.二叉樹的性質: 1) 二叉樹第i層上的結點數最多為2^(i-1); 2) 深度為k的二叉樹至多有2^k-1個結點; 3) 在任意二叉樹中,葉子數為n0,度為2的結點數為n2,則n0=n2+1; 15.滿二叉樹是一棵深度為k的且有2^k-1個結點的二叉樹; 16.完全二叉樹是至多在最下兩層上結點的度數可以小於2,並且最下層的結點集中在該層最左的位置的二叉樹; 17.具有N個結點的完全二叉樹的深度為log2N取整加1; 18.二叉樹的儲存結構 (1)順序儲存結構:把一棵有n個結點的完全二叉樹,從樹根起自上而下、從左到右對所有結點編號,然後依次儲存在一個向量b[0~n]中,b[1~n]存放結點,b[0]存放結點總數。 各個結點編號間的關係: 1) i=1是根結點;i>1則雙親結點是i/2取整; 2) 左孩子是2i, 右孩子是2i+1;(要小於n) 3) i>(n/2取整)的結點是葉子; 4) 奇數沒有右兄弟,左兄弟是i-1; 5) 偶數沒有左兄弟,右兄弟是i+1; (2)鏈式儲存結構 結點的結構為:lchild|data|rchild ;相應的型別說明: typedef char data; typedef struct node{  datatype data;  structnode *lchild , *rchild; }bintnode; typedef bintnode * bintree; 19.在二叉樹中所有型別為bintnode的結點和一個指向開始結點的bintree型別的頭指標構成二叉樹的鏈式儲存結構稱二叉連結串列。 20.二叉連結串列由根指標唯一確定。在n個結點的二叉連結串列中有2n個指標域,其中n+1個為空。   21.二叉樹的遍歷方式有:前序遍歷、中序遍歷、後序遍歷。時間複雜度為O(n)。 22.線索二叉樹:利用二叉連結串列中的n+1個空指標域存放指向某種遍歷次序下的前趨和後繼結點的指標,這種指標稱線索。加線索的二叉連結串列稱線索連結串列。相應二叉樹稱線索二叉樹。 23.線索連結串列結點結構:lchild|ltag|data|rtag|rchild;ltag=0,lchild是指向左孩子的指標;ltag=1,lchild是指向前趨的線索;rtag=0,rchild是指向右孩子的指標;rtag=1,rchild是指向後繼的線索; 24.查詢*p在指定次序下的前趨和後繼結點。演算法的時間複雜度為O(h)。線索對查詢前序前趨和後序後繼幫助不大。 25.遍歷線索二叉樹。時間複雜度為O(n)。   26.樹、森林與二叉樹的轉換 (1)樹、森林與二叉樹的轉換 1)樹與二叉樹的轉換:1}所有兄弟間連線;2}保留與長子的連線,去除其它連線。該二叉樹的根結點的右子樹必為空。 2)森林與二叉樹的轉換:1}將所有樹轉換成二叉樹;2}將所有樹根連線。 (2)二叉樹與樹、森林的轉換。是以上的逆過程。 27.樹的儲存結構 (1)雙親連結串列表示法:為每個結點設定一個parent指標,就可唯一表示任何一棵樹。Data|parent (2)孩子連結串列表示法:為每個結點設定一個firstchild指標,指向孩子連結串列頭指標,連結串列中存放孩子結點序號。Data|firstchild。 (3雙親孩子連結串列表示法:將以上方法結合。Data|parent|firstchild (4)孩子兄弟連結串列表示法:附加兩個指向左孩子和右兄弟的指標。Leftmostchild|data|rightsibling 28.樹和森林的遍歷:前序遍歷一棵樹等價於前序遍歷對應二叉樹;後序遍歷等價於中序遍歷對應二叉樹。   29.最優二叉樹(哈夫曼樹):樹的路徑長度是從樹根到每一結點的路徑長度之和。將樹中的結點賦予實數稱為結點的權。 30.結點的帶權路徑是該結點的路徑長度與權的乘積。樹的帶權路徑長度又稱樹的代價,是所有葉子的帶權路徑長度之和。 31.帶權路徑長度最小的二叉樹稱最優二叉樹(哈夫曼樹)。 32.具有2n-1個結點其中有n個葉子,並且沒有度為1的分支結點的樹稱為嚴格二叉樹。 33.哈夫曼編碼  34.對字符集編碼時,要求字符集中任一字元的編碼都不是其它字元的編碼字首,這種編碼稱字首碼。 35.字元出現頻度與碼長乘積之和稱檔案總長;字元出現概率與碼長乘積之和稱平均碼長; 36.使檔案總長或平均碼長最小的字首碼稱最優字首碼 37.利用哈夫曼樹求最優字首碼,左為0,右為1。編碼平均碼長最小;沒有葉子是其它葉子的祖先,不可能出現重複字首。   第 七 章   圖

1.圖:圖G是由頂點集V和邊集E組成,頂點集是有窮非空集,邊集是有窮集; 2.G中每條邊都有方向稱有向圖;有向邊稱弧;邊的始點稱弧尾;邊的終點稱弧頭;G中每條邊都沒有方向的稱無向圖。

3.頂點n與邊數e的關係:無向圖的邊數e介於0~n(n-1)/2之間,有n(n-1)/2條邊的稱無向完全圖;有向圖的邊數e介於0~n(n-1)之間,有n(n-1)條邊的稱有向完全圖; 4.無向圖中頂點的度是關聯與頂點的邊數;有向圖中頂點的度是入度與出度的和。 所有圖均滿足:所有頂點的度數和的一半為邊數。

5.圖G(V,E),如V’是V的子集,E’是E的子集,且E’中關聯的頂點均在V’中,則G’(V’,E’)是G的子圖。

6.在有向圖中,從頂點出發都有路徑到達其它頂點的圖稱有根圖; 7.在無向圖中,任意兩個頂點都有路徑連通稱連通圖;極大連通子圖稱連通分量; 8.在有向圖中,任意順序兩個頂點都有路徑連通稱強連通圖;極大連通子圖稱強連通分量;

9.將圖中每條邊賦上權,則稱帶權圖為網路。

10.圖的儲存結構: (1)鄰接矩陣表示法:鄰接矩陣是表示頂點間相鄰關係的矩陣。n個頂點就是n階方陣。 無向圖是對稱矩陣;有向圖行是出度,列是入度。 (2)鄰接表表示法:對圖中所有頂點,把與該頂點相鄰接的頂點組成一個單鏈表,稱為鄰接表,adjvex|next,如要儲存頂點資訊加入data;對所有頂點設立頭結點,vertex|firstedge,並順序儲存在一個向量中;vertex儲存頂點資訊,firstedge儲存鄰接表頭指標。 11.鄰接矩陣表示法與鄰接表表示法的比較: 1) 鄰接矩陣是唯一的,鄰接表不唯一; 2) 儲存稀疏圖用鄰接表,儲存稠密圖用鄰接矩陣; 3) 求無向圖頂點的度都容易,求有向圖頂點的度鄰接矩陣較方便; 4) 判斷是否是圖中的邊,鄰接矩陣容易,鄰接表最壞時間為O(n); 5) 求邊數e,鄰接矩陣耗時為O(n^2),與e無關,鄰接表的耗時為O(e+n);

12.圖的遍歷: (1)圖的深度優先遍歷:類似與樹的前序遍歷。按訪問頂點次序得到的序列稱DFS序列。 對鄰接表表示的圖深度遍歷稱DFS,時間複雜度為O(n+e); 對鄰接矩陣表示的圖深度遍歷稱DFSM,時間複雜度為O(n^2); (2)圖的廣度優先遍歷:類似與樹的層次遍歷。按訪問頂點次序得到的序列稱BFS序列。 對鄰接表表示的圖廣度遍歷稱BFS,時間複雜度為O(n+e); 對鄰接矩陣表示的圖廣度遍歷稱BFSM,時間複雜度為O(n^2);

13. 將沒有迴路的連通圖定義為樹稱自由樹。 14.生成樹:連通圖G的一個子圖若是一棵包含G中所有頂點的樹,該子圖稱生成樹。 有DFS生成樹和BFS生成樹,BFS生成樹的高度最小。 非連通圖生成的是森林。 15.最小生成樹:將權最小的生成樹稱最小生成樹。(是無向圖的演算法) (1)普里姆演算法: 1) 確定頂點S、初始化候選邊集T[0~n-2];formvex|tovex|lenght 2) 選權值最小的T[i]與第1條記錄交換; 3) 從T[1]中將tovex取出替換以下記錄的fromvex計算權;若權小則替換,否則不變; 4) 選權值最小的T[i]與第2條記錄交換; 5) 從T[2]中將tovex取出替換以下記錄的fromvex計算權;若權小則替換,否則不變; 6) 重複n-1次。 初始化時間是O(n),選輕邊的迴圈執行n-1-k次,調整輕邊的迴圈執行n-2-k;演算法的時間複雜度為O(n^2),適合於稠密圖。 (2)克魯斯卡爾演算法: 1) 初始化確定頂點集和空邊集;對原邊集按權值遞增順序排序; 2) 取第1條邊,判斷邊的2個頂點是不同的樹,加入空邊集,否則刪除; 3) 重複e次。 對邊的排序時間是O(elog2e);初始化時間為O(n);執行時間是O(log2e);演算法的時間複雜度為O(elog2e),適合於稀疏圖。

16. 路徑的開始頂點稱源點,路徑的最後一個頂點稱終點; 17.單源最短路徑問題:已知有向帶權圖,求從某個源點出發到其餘各個頂點的最短路徑; 18.單目標最短路徑問題:將圖中每條邊反向,轉換為單源最短路徑問題; 19.單頂點對間最短路徑問題:以分別對不同頂點轉換為單源最短路徑問題; 20.所有頂點對間最短路徑問題:分別對圖中不同頂點對轉換為單源最短路徑問題;

21.迪傑斯特拉演算法: 1) 初始化頂點集S[i],路徑權集D[i],前趨集P[i]; 2) 設定S[s]為真,D[s]為0; 3) 選取D[i]最小的頂點加入頂點集; 4) 計算非頂點集中頂點的路徑權集; 5) 重複3)n-1次。 演算法的時間複雜度為O(n^2)。

22.拓撲排序:對一個有向無環圖進行拓撲排序,是將圖中所有頂點排成一個線性序列,滿足弧尾在弧頭之前。這樣的線性序列稱拓撲序列。 (1)無前趨的頂點優先:總是選擇入度為0的結點輸出並刪除該頂點的所有邊。 設定各個頂點入度時間是O(n+e),設定棧或佇列的時間是O(n),演算法時間複雜度為O(n+e)。 (2)無後繼的頂點優先:總是選擇出度為0的結點輸出並刪除該頂點的所有邊。 設定各個頂點出度時間是O(n+e),設定棧或佇列的時間是O(n),演算法時間複雜度為O(n+e)。 求得的是逆拓撲序列。   第 八 章   排 序   1.檔案:由一組記錄組成,記錄有若干資料項組成,唯一標識記錄的資料項稱關鍵字; 2.排序是將檔案按關鍵字的遞增(減)順序排列;

3.排序檔案中有相同的關鍵字時,若排序後相對次序保持不變的稱穩定排序,否則稱不穩定排序;

4.在排序過程中,檔案放在記憶體中處理不涉及資料的內、外存交換的稱內排序,反之稱外排序;

5.排序演算法的基本操作:1)比較關鍵字的大小;2)改變指向記錄的指標或移動記錄本身。

6.評價排序方法的標準:1)執行時間;2)所需輔助空間,輔助空間為O(1)稱就地排序;另要注意演算法的複雜程度。

7.若關鍵字型別沒有比較運算子,可事先定義巨集或函式表示比較運算。

8.插入排序 (1)直接插入排序 演算法中引入監視哨R[0]的作用是:1)儲存R[i]的副本;2)簡化邊界條件,防止迴圈下標越界。 關鍵字比較次數最大為(n+2)(n-1)/2;記錄移動次數最大為(n+4)(n-1)/2; 演算法的最好時間是O(n);最壞時間是O(n^2);平均時間是O(n^2);是一種就地的穩定的排序; (2)希爾排序 實現過程:是將直接插入排序的間隔變為d。d的取值要注意:1)最後一次必為1;2)避免d值互為倍數; 關鍵字比較次數最大為n^1.25;記錄移動次數最大為1.6n^1.25; 演算法的平均時間是O(n^1.25);是一種就地的不穩定的排序;

9.交換排序 (1)氣泡排序 實現過程:從下到上相鄰兩個比較,按小在上原則掃描一次,確定最小值,重複n-1次。 關鍵字比較次數最小為n-1、最大為n(n-1)/2;記錄移動次數最小為0,最大為3n(n-1)/2; 演算法的最好時間是O(n);最壞時間是O(n^2);平均時間是O(n^2);是一種就地的穩定的排序; (2)快速排序 實現過程:將第一個值作為基準,設定i,j指標交替從兩頭與基準比較,有交換後,交換j,i。i=j時確定基準,並以其為界限將序列分為兩段。重複以上步驟。 關鍵字比較次數最好為nlog2n+nC(1)、最壞為n(n-1)/2; 演算法的最好時間是O(nlog2n);最壞時間是O(n^2);平均時間是O(nlog2n);輔助空間為O(log2n);是一種不穩定排序;

10.選擇排序 (1)直接選擇排序 實現過程:選擇序列中最小的插入第一位,在剩餘的序列中重複上一步,共重複n-1次。 關鍵字比較次數為n(n-1)/2;記錄移動次數最小為0,最大為3(n-1); 演算法的最好時間是O(n^2);最壞時間是O(n^2);平均時間是O(n^2);是一種就地的不穩定的排序; (2)堆排序 實現過程:把序列按層次填入完全二叉樹,調整位置使雙親大於或小於孩子,建立初始大根或小根堆,調整樹根與最後一個葉子的位置,排除該葉子重新調整位置。 演算法的最好時間是O(nlog2n);最壞時間是O(nlog2n);平均時間是O(nlog2n);是一種就地的不穩定排序;

11.歸併排序 實現過程:將初始序列分為2個一組,最後單數輪空,對每一組排序後作為一個單元,對2個單元排序,直到結束。 演算法的最好時間是O(nlog2n);最壞時間是O(nlog2n);平均時間是O(nlog2n);輔助空間為O(n);是一種穩定排序;

12.分配排序 (1)箱排序 實現過程:按關鍵字的取值範圍確定箱子的個數,將序列按關鍵字放入箱中,輸出非空箱的關鍵字。 在桶內分配和收集,及對各桶進行插入排序的時間為O(n),演算法的期望時間是O(n),最壞時間是O(n^2)。 (2)基數排序 實現過程:按基數設定箱子,對關鍵字從低位到高位依次進行箱排序。 演算法的最好時間是O(d*n+d*rd);最壞時間是O(d*n+d*rd);平均時間是O(d*n+d*rd);輔助空間O(n+rd);是一種穩定排序;

13.各種內部排序方法的比較和選擇: (1)按平均時間複雜度分為: 1) 平方階排序:直接插入、直接選擇、氣泡排序; 2) 線性對數階:快速排序、堆排序、歸併排序; 3) 指數階:希爾排序; 4) 線性階:箱排序、基數排序。

(2)選擇合適排序方法的因素: 1)待排序的記錄數;2)記錄的大小;3)關鍵字的結構和初始狀態;4)對穩定性的要求; 5)語言工具的條件;6)儲存結構;  7)時間和輔助空間複雜度。

(3)結論: 1) 若規模較小可採用直接插入或直接選擇排序; 2) 若檔案初始狀態基本有序可採用直接插入、冒泡或隨機快速排序; 3) 若規模較大可採用快速排序、堆排序或歸併排序; 4) 任何藉助於比較的排序,至少需要O(nlog2n)的時間,箱排序和基數排序只適用於有明顯結構特徵的關鍵字; 5) 有的語言沒有提供指標及遞迴,使歸併、快速、基數排序演算法複雜; 6) 記錄規模較大時為避免大量移動記錄可用連結串列作為儲存結構,如插入、歸併、基數排序,但快速、堆排序在連結串列上難以實現,可提取關鍵字建立索引表,然後對索引表排序。   第 九 章   查 找

1.查詢的同時對錶做修改操作(如插入或刪除)則相應的表稱之為動態查詢表,否則稱之為靜態查詢表。 2.衡量一個查詢演算法次序優劣的標準是在查詢過程中對關鍵字需要執行的平均比較次數(即平均查詢長度ASL).

3.線性表上進行查詢的方法主要有三種:順序查詢、二分查詢和分塊查詢。 (1)順序查詢的演算法基本思想:是從表的一端開始順序掃描線性表,依次將掃描到的結點關鍵字與給定值K比較,若當前掃描到的結點關鍵字與k相等則查詢成功;若掃描結束後,仍未找到關鍵字等於K的結點,則查詢失敗。 1)順序查詢方法可用鏈式儲存結構和順序儲存結構實現。 2)在順序儲存結構的順序查詢演算法中所設的哨兵是為了簡化迴圈的邊界條件而引入的附加結點(元素),其作用是使for迴圈中省去判定防止下標越界的條件從而節省了比較的時間。 3)在等概率情況下,查詢成功時其平均查詢長度約為表長的一半(n+1)/2.查詢失敗的話其平均查詢長度為n+1. (2)二分查詢(又稱折半查詢),它的演算法思想:是對一有序表中的元素,從初始的查詢區間開始,每經過一次與當前查詢區間的中點位置上的結點關鍵字進行比較,若相等,則查詢成功,否則,當前查詢區間的縮小一半,按k值大小在某半個區間內重複相同的步驟進行查詢,直到查詢成功或失敗為止。 1)二分查詢在等概率的情況下查詢成功的平均查詢長度ASL為lg(n+1)-1,在查詢失敗時所需比較的關鍵字個數不超過判定樹的深度,最壞情況下查詢成功的比較次數也不超過判定樹的深度┌lg(n+1)┐(不小於lg(n+1)的最小整數) 2)二分查詢只適用於順序儲存結構而不能用鏈式儲存結構實現。因為連結串列無法進行隨機訪問,如果要訪問連結串列的中間結點,就必須先從頭結點開始進行依次訪問,這就要浪費很多時間,還不如進行順序查詢,而且,用鏈儲存結構將無法判定二分的過程是否結束,因此無法用連結串列實現二分查詢。 (3)分塊查詢(又稱索引順序查詢)的基本思想:是將原表分成若干塊,各塊內部不一定有序,但表中的塊是"分塊有序"的,並抽取各塊中的最大關鍵字及其起始位置建立索引表。因為索引表是有序的,分塊查詢就是先用二分查詢或順序查詢確定待查結點在哪一塊,然後在已確定的塊中進行順序查詢(不能用二分查詢,因為塊內是無序的)。分塊查詢實際上是兩次查詢過程,它的演算法效率介與順序查詢和二分查詢之間。

4.以上三種查詢方法的比較如下表: 查詢演算法 儲存結構 優點 缺點 適用於  順序查詢 順序結構 連結串列結構  演算法簡單且對錶的結構無任何要求 查詢效率低 n較小的表的查詢和查詢較少但改動較多的表(用連結串列作儲存結構)  二分查詢 順序結構 查詢效率高 關鍵字要有序且只能用順序儲存結構實現 特別適用於一經建立就很少改動又經常需要查詢的線性表  分塊查詢 順序結構 連結串列  在表中插入或刪除記錄時就只要在該記錄所屬塊內操作,因為塊內記錄的存放是隨意的,所以插入和刪除比較容易 要增加一個輔助陣列的儲存空間,並要進行將初始表分塊排序運算 適用於有分塊特點的記錄,如一個學校的學生登記表可按系號或班號分塊。  5.樹的查詢:以樹做為表的組織形式有一個好處,就是可以實現對動態查詢表進行高效率的查詢。這裡講到了二叉排序樹和B-樹,以及在這些樹表上進行查詢和修改操作的方法。 6.二叉排序樹(BST)又稱二叉查詢樹,其定義是:二叉排序樹要或者是空樹或者滿足如下性質的二叉樹: 1)若它的左子樹非空,則左子樹上所有結點的值均小於根結點的值; 2)若它的右子樹非空,則右子樹上所有結點的值均大於根結點的值; 3)左、右子樹本身又是一棵二叉排序樹。

(1)二叉排序樹實際上是滿足BST性質的二叉樹。  (2)二叉排序樹的插入、建立的演算法平均時間效能是O(nlgn),但其執行時間約為堆排序的2至3倍。二叉排序樹的刪除操作可分三種情況進行處理: 1)*P是葉子,則直接刪除*P,即將*P的雙親*parent 中指向*P的指標域置空即可。 2)*P只有一個孩子*child,此時只需將*child和*p的雙親直接連線就可刪去*p. 3)*p有兩個孩子,則將操作轉換成刪除*p結點的中序後繼,在刪去它之前把這個結點的資料複製到原來要刪的結點位置上就完成了刪除。 (3)二叉排序樹上的查詢和二分查詢類似,它的關鍵字比較次數不超過樹的深度。在最好的情況下,二叉排序樹在生成的過程中比較勻稱,此時的叉排序樹是平衡的二叉樹(也就是樹中任一結點的左右子樹的高度大致相同),它的高度約為1.44lgn,完全平衡的二叉樹高度約為lgn.在最壞的情況下,輸入的例項產生的二叉排序樹的高度將達到O(n),這種情況應當避免。

7.關於B-樹(多路平衡查詢樹)。它適合在磁碟等直接存取裝置上組織動態的查詢表,是一種外查詢演算法。 B樹的階是指B-樹的度數,B-樹的結點具有k個孩子時,該結點必有k-1(k>=2)個關鍵字。 實際上B-樹是二叉排序樹的推廣,它就是一棵m叉樹,且滿足四個性質,這些性質與二叉排序樹有相似之處,請仔細理解之。

8.上面的幾種查詢方法均是建立在比較關鍵字的基礎上,因此它們的平均和最壞情況下所需的比較次數的下界是lgn+O(1).

9.雜湊技術:可以無需任何比較就找到待查關鍵字,其查詢的期望時間為O(1). 散列表的概念:就是將所有可能出現的關鍵字的集合U(全集)對映到一個表T[0..m-1]的下標集上,這個表就是散列表。 10.而關鍵字與這個表地址之間以什麼樣的關係發生聯絡呢,這就要通過一個函式來建立,這個函式是以U中的關鍵字為自變數,以相應結點的儲存地址為函式值,它就稱為雜湊函式。將結點按其關鍵字的雜湊地址儲存到散列表的過程稱為雜湊。 11.根據某種雜湊函式,一個關鍵字的雜湊函式值是唯一的,但是有可能兩個或多個不同關鍵字的函式值是相同的,這時就會把幾個結點儲存到同一個表位置上,這時就造成衝突(或碰撞)現象,這兩個關鍵字稱為該雜湊函式的同義詞。 要完全(不是"安全")避免衝突需滿足兩個條件,一是關鍵字集合U不大於散列表長m,另一個是選擇合適的雜湊函式,如果用h(ki)=0)這樣的函式的話,看看有什麼結果。

12.通常情況下U總是大大於m的,因此不可能完全避免衝突。衝突的頻繁程度還與表的填滿程度相關。裝填因子α表示表中填入的結點數與表長的比值,通常取α≤1,因為α越大,表越滿,衝突的機會也越大。 13.雜湊函式的選擇有兩條標準:簡單和均勻。看看h(ki)=0這樣的函式,簡單是簡單,但絕不均勻。

14.下面是常見的幾種雜湊函式構的造方法: (1)平方取中法  (2)除餘法:它是用表長m來除關鍵字,取餘數作為雜湊地址。若選除數m是關鍵字的基數的冪次,就會使得高位不同而低位相同的關鍵字互為同義詞。因此最好選取素數為除數. (3)相乘取整法:有兩個步驟,先用關鍵字key乘上某個常數A(0) (4)隨機數法,此法以關鍵字為自變數,通過一隨機函式得到的值作為雜湊地址。

15.處理衝突的方法:當不可避免發生衝突時,就必須對衝突加以解決,使發生衝突的同義詞能儲存到表中。

16.通常有兩類方法處理衝突:開放定址法和拉鍊法。前者是將所有結點均存放在雜湊T[0..m-1]中,後者是將互為同義詞的結點鏈成一個單鏈表,而將此連結串列的頭指標放在散列表中。

17.開放定址法的一般形式為:hi=(h(key)+di)%m 1≤i≤m-1 18.開放定址法要求散列表的裝填因子α≤1。開放定址法又有線性探查法、二次探查法和雙重雜湊法之分。 (1)由於線性探查法在構造散列表時,遇到衝突(有同義詞)的時候會按探查序列向後面的空地址插入,從而使原來應插入到此位置的結點又與它發生衝突,當一連串的位置均已有結點時,本應插入到這些位置的結點又只能將其插入到更後面的同一個空結點上,這種雜湊地址不同的結點爭奪同一個後繼雜湊地址的現象就是聚集或堆積。(注意,同義詞發生衝突不是堆積) 為了減小堆積現象的發生,可以用二次探查法和雙重雜湊法進行探查。 (2)拉鍊法解決衝突的做法是,將所有關鍵字為同義詞的結點連結在同一個單鏈表中。

19.與開放定址法相比,拉鍊法有如下幾個優點: (1)拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查詢長度較短;(簡單無堆積) (2)由於拉鍊法中各連結串列上的結點空間是動態申請的,故它更適於造表前無法確定表長的情況;(動態申表長) (3)開放定址法為減少衝突要求裝填因子α較小,當結點規模較大時會浪費很多空間,拉鍊法中α可以大於1,且結點較大時,其指標域可忽略不計,因此節省空間;(空間可節省) (4)拉鍊法構造的散列表刪除結點易實現,而開放定址法中則不能真正刪除結點只能做刪除標記。(刪除易實現) 20.拉鍊法也有缺點:當結點規模較小時,用拉鍊法中的指標域也要佔用額外空間,還是開放定址法省空間。

21.在散列表上的運算有查詢、插入和刪除,主要是查詢。這三個操作的演算法並不複雜,也容易理解。關於查詢操作的時間效能,可看教材p202的表9.1。由表可見,散列表的平均查詢長度不是結點個數n的函式,而是裝填因子α的函式。α越小,衝突的概率越小,但空間的浪費將增加,當α大小合適時,散列表上的平均查詢長度就是一個常數,時間效能是O(1).    第 十 章   文 件

1. 對資料結構來說,檔案是性質相同的記錄的集合。 2.  2.記錄是檔案中存取的基本單位,資料項是檔案可使用的最小單位,資料項有時稱欄位或者屬性。主關鍵字項(唯一標識一個記錄的欄位)、次關鍵字項、主關鍵字、次關鍵字。單關鍵字檔案、多關鍵字檔案等。

3.檔案的邏輯結構是一種線性結構。

4.檔案上的操作主要有兩類:檢索和維護。並有實時和批量處理兩種處理方式。

5.檔案的儲存結構是指檔案在外存上的組織方式,基本的組織方式有:順序組織、索引組織、雜湊組織和鏈組織。檔案組織的各種方式往往是這四種基本方式的結合。

6.常用的檔案組織方式:順序檔案、索引檔案、雜湊檔案和多關鍵字檔案。

7.評價一個檔案組織的效率,是執行檔案操作所花費的時間和檔案組織所需的儲存空間。通常檔案組織的主要目的,是為了能高效、方便地對檔案進行操作,而檢索功能的多寡和速度的快慢,是衡量檔案操作質量的重要標誌。

8.順序檔案:是指按記錄進入檔案的先後順序存放、其邏輯順序和物理順序一致的檔案。 1)一切儲存在順序儲存器(如磁帶)上的檔案都只能順序檔案。這種順序檔案只能按順序查詢法存取(注意,沒有折半法了) 2)儲存在直接存取儲存器(如磁碟)上的順序檔案可以順序查詢法存取,也可以用分塊查詢法或二分查詢法存取。 3)順序檔案多用於磁帶。

9.索引檔案:組織方式:通常是在檔案本身(主檔案)之外,另外建立一張表,它指明邏輯記錄和物理記錄之間一一對應的關係,這張表就叫做索引表,它和主檔案一起構成索引檔案。 1)索引非順序檔案中的索引表為稠密索引。索引順序檔案中的索引表為稀疏索引。 2)若記錄很大使得索引表也很大時,可對索引表再建立索引,稱為查詢表。通常可達四級索引。

10.索引順序檔案:是最常用的檔案組織:因為索引順序檔案的主檔案也是有序的,所以它既適合於隨機存取也適合於順序存取。另一方面,索引非順序檔案的索引是稠密索引,而索引順序檔案的稀疏索引,佔用空間較少,因此索引順序檔案是最常用的一種檔案組織。  1)索引順序檔案常用的有兩種:ISAM檔案和VSAM檔案

11.雜湊檔案:是利用雜湊儲存方式組織的檔案,亦稱為直接存取檔案。 1)它類似於散列表,即根據檔案中關鍵字的特點,設計一個雜湊函式和處理衝突的方法,將記錄雜湊到儲存裝置上。與散列表不同的是,對於檔案來說,記錄通常是成組存放的,若干個記錄組成一個儲存單位,稱為桶。對雜湊而言,處理衝突的方法主要採用拉鍊法。  2)雜湊檔案的優點是:檔案隨機存放,記錄不需要排序;插入刪除方便;存取速度快;不需要索引區,節省儲存空間。缺點是:不能進行順序存取,只能按關鍵字隨機存取,且詢問方式限地簡單詢問,需要重新組織檔案。

12.對被查詢的次關鍵字也建立相應的索引,則這種包含有多個次關鍵字索引的檔案稱為多關鍵字檔案。 1)兩種多關鍵字檔案的組織方法:多重表文件和倒排表。

2)一般的檔案組織中,是先找記錄,然後再找到該記錄所含的各次關鍵字;而倒排檔案是先給定次關鍵字,然後查詢含有該次關鍵字的各個記錄,因此稱為倒排。