1. 程式人生 > >第二章作業題3-連結串列(2)

第二章作業題3-連結串列(2)

一、選擇題

1、這裡寫圖片描述

非空且迴圈,所以尾結點的下一個是頭結點

2、這裡寫圖片描述

D是s的前指標指向p,s的下一個為p的下一個,注意這個時候p所指的下一個還沒變,p所指的下一個的前一個是s,p的下一個是s(這個時候p所指的下一個才發生了變化)。

3、這裡寫圖片描述

刪除p所指的結點也就是p,所以就是p的前一個的下一個指向p的下一個,p的下一個的前一個指向p的前一個

4、這裡寫圖片描述

(1)尾指標的定義: 尾指標,指向最後一個元素

(2)C雖然可以直接獲得第一個元素,但是想要獲得最後一個元素卻需要遍歷整個連結串列。而B給出的是帶有尾結點的單迴圈連結串列,這樣就可以直接得到最後一個元素,想要得到第一個元素只需要再遍歷一個元素就可以

(3)單鏈表只能往前移動 問題實質是用最快的時間找到 最後一個元素和頭元素,根據尾指標通過O(1)的時間找到最後一個元素,然後根據連結串列是單迴圈,往前移動一個元素就是頭元素,綜上所述答案為:僅有尾指標的單迴圈連結串列)

5、這裡寫圖片描述

(1)題目問的是哪一種方式更省時間

(2)在最後一個結點附近操作,所以要先找到最後一個結點附近

帶頭結點的雙向迴圈連結串列,頭結點的前驅即可找到最後一個結點,可以快速插入,再向前可以找到最後一二個結點快速刪除 單鏈表找到連結串列尾部需要掃描整個連結串列 雙鏈表找到連結串列尾部也需要掃描整個連結串列 單迴圈連結串列只有單向指標,找到連結串列尾部也需要掃描整個連結串列

6、這裡寫圖片描述

7、這裡寫圖片描述

(1)在最後一個結點之後插入一個結點需要找到最後一個結點,刪除最後一個結點需要的是找到最後一個結點的前一個,所以最快的是C。

8、這裡寫圖片描述

9、這裡寫圖片描述

(1)在最後一個結點之後插入一個結點需要找到最後一個結點,刪除最後一個結點需要的是找到最後一個結點的前一個,所以最快的是D,代表頭附加結點而且雙迴圈。

(2)問題出現在查詢效率上,連結串列最常用的操作是在末尾插入節點和刪除尾節點 在尾巴插入 刪除操作。都需要知道他的前導,而單鏈表要查詢到最有一個元素需要遍歷全部連結串列,迴圈雙鏈表直接可以查到前導。

10、這裡寫圖片描述

(1)在最後一個結點後插入或刪除第一個,如果僅僅需要刪除第一個的話,僅帶頭結點即可,但是在最後一個結點後插入,必須要找到最後一個元素,這個時候D最快。

11、這裡寫圖片描述

B刪除最後一個的話,需要找到前一個,因為是單鏈表,所以與長度有關。A、C與頭指標有關

12、這裡寫圖片描述

(1)刪除第一個,找頭指標,刪除最後一個,找它的前一個,最後一個元素後面找最後一個元素。所以如果是涮迴圈連結串列的話是最快的,因為涉及頭指標,最後一個元素的前一個,最後一個元素

這類題就是看需要找的元素的位置在哪即可,刪除和插入都要找到其前一個位置

13、這裡寫圖片描述

14、這裡寫圖片描述

(1)right是後面,left是前一個

15、這裡寫圖片描述

16、這裡寫圖片描述

17、設有一個雙向迴圈連結串列,每個結點中除有left、data和right三個域外,還增設了一個訪問頻度域freq,freq 的初值為零。每當連結串列進行一次查詢操作後,被訪問結點的頻度域值便增1,同時調整連結串列中結點的次序,使連結串列按結點頻度值非遞增有序的次序排列。下列演算法是符合上述要求的查詢演算法,請將該演算法補充完整。 (4分)

typedef struct Node{
ElemType  data; 
   struct Node *left;  
   struct Node *right; 
intfreq;          
} DNode;
DNode *locate_DList(DNode *&L, ElemType x)
{ //在表L中查詢元素x,查詢成功則調整結點頻度域值及結點位置,並返回結點地址;
//查詢不成功則返回NULL
DNode *p=L, *q;
   if (L==NULL)  return NULL;
   while (p->data!=x && p->right!=L)  p=p->right;
   if (p->data!=x)  return NULL;
   p->freq++; 
   q=p->left;
   while (q!=L && q->freq<=p->freq)  q=q->left;  //查詢插入位置
   if (q==L && q->freq<=p->freq) {  //需將p結點插在頭結點L前
//將p結點先從連結串列中摘下來
p->left->right=p->right; 
      p->right->left=p->left;   
               //將p結點插在L結點前
      p->right=L;
      p->left=L->left;
      L->left->right=p;
      L->left=p;
      L=p;
   }
   else if (q!=p->left ) {  //若q不是p的前驅,則需調整結點位置,將p結點插在q結點後
//將p結點先從連結串列中摘下來
      p->left->right=p->right; 
      p->right->left=p->left;
      ______________ //將p結點插在q結點後         
   }
   return p;
}

這裡寫圖片描述

18、 這裡寫圖片描述

二、程式設計題