陣列 PTA 類似二分法解決有序陣列的插入

2021-10-10 13:28:25 字數 3776 閱讀 7538

高等教育出版社教材-浙大版《資料結構(第2版)》題目集。

有序陣列的插入

本題要求將任一給定元素插入從大到小排好序的陣列中合適的位置,以保持結果依然有序。

函式介面定義:

bool insert

( list l, elementtype x )

;

其中list結構定義如下:

typedef

int position;

typedef

struct lnode *list;

struct lnode

;

l是使用者傳入的乙個線性表,其中elementtype元素可以通過》、==、《進行比較,並且題目保證傳入的資料是遞減有序的。函式insert要將x插入data中合適的位置,以保持結果依然有序(注意:元素從下標0開始儲存)。但如果x已經在data中了,就不要插入,返回失敗的標記false;如果插入成功,則返回true。另外,因為data中最多只能存maxsize個元素,所以如果插入新元素之前已經滿了,也不要插入,而是返回失敗的標記false

裁判測試程式樣例:

#include

#include

#define maxsize 10

typedef

enum

bool;

typedef

int elementtype;

typedef

int position;

typedef

struct lnode *list;

struct lnode

;list readinput()

;/* 裁判實現,細節不表。元素從下標0開始儲存 */

void

printlist

( list l )

;/* 裁判實現,細節不表 */

bool insert

( list l, elementtype x )

;int

main()

/* 你的**將被嵌在這裡 */

輸入樣例1:

5

351287

310

輸出樣例1:

35

121087

3last =

5

輸入樣例2:

6

3512108

738

輸出樣例2:

insertion failed.

3512108

73last =

5

啊,關於此題,想說三點:

① 「二分插入」的方法由二分查詢演變而來,原理是先進行二分查詢,直至查詢區間只有兩個元素,就把目標元素插入它們中間。

② 這種插入法有一處需要注意。請比較如下**:

if

(begin +

1== end)

if(l->data[mid]

> x)

return

innerinsert

(l, mid +

1, end, x);if

(l->data[mid]

< x)

return

innerinsert

(l, begin, mid -

1, x)

;

和如下**:

if

(begin +

1== end)

if(l->data[mid]

> x)

return

innerinsert

(l, mid, end, x);if

(l->data[mid]

< x)

return

innerinsert

(l, begin, mid, x)

;

第一段是由二分查詢無腦改來的。值得注意的是第一種方法將無法把目標元素插入mid和mid+1(mid和mid-1)之間。換句話說,我們只能把元素插入至給定序列的內部,而首尾是做不到的。由此必須使用第二段**。

這樣可以解決一部分問題,但是我們能類似地將begin-1和end+1作為查詢序列進行查詢嗎?這可能會導致溢位問題。所以我們直接在最開始時就判斷目標元素是否將被放至首尾:

bool insert

(list l, elementtype x)

這樣一來,與其說我們寫的是「二分插入」,不如說是「內部二分插入」,因為它只能解決內部插入問題。故名為innerinsert

bool innerinsert

(list l, position begin, position end, elementtype x)

if(l->data[mid]

> x)

return

innerinsert

(l, mid, end, x);if

(l->data[mid]

< x)

return

innerinsert

(l, begin, mid, x)

;}

至於「外部二分插入」的解決,我們留給了總體的二分插入函式insert.

③ 這一條是普適經驗:當函式的return出口非常多時,建議用翁愷在mooc中提到的「唯一出口」原則,因為不小心真的會漏掉**的return而且半天都發現不了!

my answer:

bool innerinsert

(list l, position begin, position end, elementtype x)

;bool doinsert

(list l, elementtype x, position index)

;bool insert

(list l, elementtype x)

bool innerinsert

(list l, position begin, position end, elementtype x)

if(l->data[mid]

> x)

return

innerinsert

(l, mid, end, x);if

(l->data[mid]

< x)

return

innerinsert

(l, begin, mid, x);}

bool doinsert

(list l, elementtype x, position index)

l->data[index]

= x;

l->last++

;return true;

}

二分法查詢有序陣列

package array public class testbinarysearch 指定查詢的元素 int num 12 用二分法查詢,返回索引 int start 0 int end arr.length 1 end的設定應該為陣列最後一位 int index 1 用於標誌是否查詢到指定元素 ...

查詢有序陣列元素 二分法

查詢的方法多種多樣,今天提到的就是對於乙個有序陣列而言最方便最高效率的方法 二分法,也叫折半查詢。具體 如下 二分法,也叫折半查詢 include include intb search int a,int left,int right,int k else if a mid k else retu...

有序陣列中二分法查詢

二分法查詢適用於資料量較大時,但是資料需要先排好順序。首先,從陣列的中間元素開始搜尋,如果該元素正好是目標元素,則搜尋過程結束,否則執行下一步。如果目標元素大於 小於中間元素,則在陣列大於 小於中間元素的那一半區域查詢,然後重複步驟1的操作。如果某一步陣列為空,則表示找不到目標元素。時間複雜度為 o...