資料結構與演算法 向量的設計及其查詢 排序演算法

2021-10-05 06:01:11 字數 4419 閱讀 4438

本文主要涉及向量(vector)的設計及其查詢、排序演算法。

1)向量的設計主要包括當前元素的數目的追蹤、記憶體的管理(擴大與縮小)、刪除、插入等基本操作;

2)向量的查詢由於向量具有隨機讀取的性質,查詢效率可以大大提公升,本文主要介紹二分查詢;

3)向量的基本排序方法主要介紹氣泡排序、插入排序與歸併排序。

向量的設計主要包括當前元素數目的追蹤和記憶體管理以進行基本的刪除、插入等操作。主要步驟如下:

1)預先分配好一定數目的記憶體供向量使用,記錄當前記憶體的基位址m_base,最大可用記憶體數目m_max_size和當前的使用的記憶體數目m_size。

2)設計記憶體增加與縮減的方法。若需要增加記憶體時,分配更大數目的記憶體並複製原資料到新空間,然後將基位址修改為新位址;若記憶體使用率較小,為了防止記憶體浪費,應該進行記憶體縮減,分配較小數目的記憶體並複製原資料到新空間,然後將基位址修改為新位址。

3)進行刪除、插入等操作的設計,在進行刪除、插入操作之前應先檢查記憶體的狀態並進行相應的增加與縮減。

向量的查詢方法根據其查詢的用途不同,我們根據向量是否有序進行不同的查詢,返回不同的結果。

1)對於無序向量,若找不到需要的資料,則直接返回-1即可;

2)但是對於有序向量的查詢,我們一般需要使用其返回結果進行插入、排序之類的操作,所以對其返回結果有特別的要求。

2.1 無序向量的查詢

無序向量的查詢一般為逐一比對,若找到則返回對應資料的索引,若找不到,則返回-1索引。

2.2 有序向量的查詢

對於有序向量的查詢,我們一般需要使用其查詢結果。假設有序向量公升序排列(也就是從小到大排列,也可能有重複資料),如果我們需要將一資料a插入到當前向量vect且仍保持vect有序,那麼

1)如果能在vect中找到該資料a,則我們希望其插入到重複資料的最後乙個;

2)如果不能找到該資料a,則我們希望返回小於該資料的第乙個資料b的位置addr_b,那麼我們可以將資料a插入資料b的後面而保持vect有序。

為了滿足上述要求,則有序向量的查詢演算法的返回值應為上述情況對應的值。普通查詢演算法如下:

//查詢演算法為半開區間,前閉後開

//適合有序向量的查詢方法,返回小於當前元素的第乙個位置

//或者返回等於該元素的重複元素的最後乙個位置

//如果沒有找到小於或等於當前元素的元素,則返回左邊界的前驅.有可能是start_index-1

//該查詢向前查詢,向後查詢與此類似

// data :需要查詢的資料

// start_index :查詢的起始索引

// stop_index :查詢的終止索引

//若查詢整個序列 則為 search(data,0,myvect.size());

template

<

typename t>

long myvector

::search

(t data,

long start_index,

long stop_index)

//如果找到則返回找到資料的索引

//如果未找到,則根據迴圈計算,返回start_index-1

return index;

}

顯然普通查詢演算法的複雜度為o(n).由於向量具有隨機讀取的性質,則其查詢效率可以大大提高,我們可以利用二分查詢來提高向量的查詢效率。其基本思路如下.設要查詢的資料為data,區間為[start_index,stop):

1)計算查詢區間[start_index,stop)中間的索引mid並獲取其值為m_base[mid];

2)若datatemplate

<

typename t>

long myvector

::binsearch

(t data,

long start_index,

long stop_index)

排序演算法主要包括氣泡排序、插入排序和歸併排序。

3.1 氣泡排序

氣泡排序的基本思路為所有的區域性有序則可形成整體有序。

在由一組整數組成的序列a[0, n - 1]中,滿足a[i - 1] <=a[i]的相鄰元素稱作順序的;否則是逆序的。不難看出,有序序列中每一對相鄰元素都是順序的,亦即,對任意1 <= i < n都有a[i - 1] <=a[i];反之,所有相鄰元素均順序的序列,也必然整體有序。

由有序序列的上述特徵,我們可以通過不斷改善區域性的有序性實現整體的有序:從前向後依次檢查每一對相鄰元素,一旦發現逆序即交換二者的位置。對於長度為n的序列,共需做n - 1次比較和不超過n - 1次交換,這一過程稱作一趟掃瞄交換。

基本思路如下:

1)通過從0-~n-1的逐次互相比較與交換,可以使序列的最大值交換到向量末尾n-1;

2)由於n-1已經放置最大值,故第二次只需要掃瞄到n-2,通過0~n-2的逐次互相比較與交換可以使序列的次大值置於n-2位置;

3)然後掃瞄序列逐漸遞減,依次找到掃瞄序列中的最大值,並置於掃瞄序列的末尾;

4)當掃瞄序列減小到1時,所有相鄰元素均順序,排序完成。

示意圖如下:

//交換二者的值

template

<

typename t>

void myvector

::swap

(t &data1, t &data2)

//氣泡排序

//排序區間前閉後開

//start_index :排序的起始索引

//stop_index :排序的結束索引

template

<

typename t>

void myvector

::bubblesort

(ulong start_index, ulong stop_index)}}

}

3.2 插入排序插入排序的演算法的思路為:

1)設當前元素data=m_base[i]之前的資料為有序的(設為front_vect),之後為無序的;

2)利用有序查詢search函式,找到當前元素m_base[i]在front_vect中的位置search_index;

3)將當前元素的資料data插入到front_vect;

4)移除當前資料,由於插入資料導致原資料索引後退1,故索引應增加1刪除

5)有序序列元素數目增加1.

示意圖如下:

//插入排序

//排序區間前閉後開

//start_index :排序的起始索引

//stop_index :排序的結束索引

template

<

typename t>

void myvector

::insertionsort

(ulong start_index, ulong stop_index)

}

3.3歸併排序歸併排序的思路如下:

1)分而治之,將無序序列遞迴地一分為前半向量和後半向量,直至無法分割;

2)從遞迴底部開始依次返回,隨著遞迴的返回,將分割的半向量從短到長依次進行有序歸併,直至完成整個向量的歸併,則排序完成。

示意圖如下所示:

/按序歸併

//start_index :歸併的起始索引

//mid_index :歸併的中間索引

//stop_index :歸併的結束索引

template

<

typename t>

void myvector

::merge

(ulong low_index,ulong mid_index,ulong high_index)

delete

front_vect;

}//歸併排序

//排序區間前閉後開

//start_index :排序的起始索引

//stop_index :排序的結束索引

template

<

typename t>

void myvector

::mergesort

(ulong start_index, ulong stop_index)

資料結構與演算法(二)向量結構

陣列 起始於位址a 物理位置連續的一段儲存空間。a a i a i x s.int p a 3,則可以認為p 0 a 3 p 2 就相當於 p p 2 其中 p指向字串 123 的第乙個元素,即 1 指標p向後移兩個元素的位址,即指向 3 而 p 2 才是基於p每次向後移乙個字串的長度,即 p 2 ...

JavaScript資料結構與演算法 棧及其應用

1.使用es6模擬棧的實現 let stack function push element pop isempty size peer clear print tostring return stack 2.棧應用之進製轉換 問題描述 將十進位制轉換為其他進製資料。function baseconv...

20120918 向量實現《資料結構與演算法分析》

include include include include include using namespace std template void change container c,const object newvalue 改變新值 template void print const list...