0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用迭代器如何實(shí)現(xiàn)指針前移或后移

UtFs_Zlgmcu7890 ? 來(lái)源:互聯(lián)網(wǎng) ? 作者:佚名 ? 2017-09-27 14:06 ? 次閱讀

近日周立功教授公開(kāi)了數(shù)年的心血之作《程序設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)》,電子版已無(wú)償性分享到電子工程師與高校群體下載,經(jīng)周立功教授授權(quán),特對(duì)本書(shū)內(nèi)容進(jìn)行連載。

>>>>1.1.1 算法接口

由于使用迭代器可以輕松地實(shí)現(xiàn)指針的前移或后移因此可以使用迭代器接口實(shí)現(xiàn)冒泡排序算法。其函數(shù)原型為

void iter_sort(iterator_if_t *p_if, iterator_t begin, iterator_t end, compare_t compare, swap_t swap) ;

其中,p_if表示算法使用的迭代器接口。begin與end是一對(duì)迭代器,表示算法的操作范圍,但不一定是容器的首尾迭代器,因此算法可以處理任何范圍的數(shù)據(jù)。為了判定范圍的有效性,習(xí)慣采用前閉后開(kāi)范圍表示法,即使用begin和end表示的范圍為[begin,end),表示范圍涵蓋bigen到end(不含end)之間的所有元素。當(dāng)begin==end時(shí),上述所表現(xiàn)的便是一個(gè)空范圍。

compare同樣也是比較函數(shù),但比較的類(lèi)型發(fā)生了變化,用于比較兩個(gè)迭代器所對(duì)應(yīng)的值。其類(lèi)型compare_t定義如下:

typedef int (*compare_t)(iterator_t it1, iterator_t it2);

swap函數(shù)用于交換兩個(gè)迭代器所對(duì)應(yīng)的數(shù)據(jù),其類(lèi)型swap_t定義如下:

typedef void (*swap_t)(iterator_t it1, iterator_t it2);

由此可見(jiàn),接口中只有迭代器,根本沒(méi)有容器的蹤影,從而做到了容器與冒泡排序算法徹底分離,基于迭代器的冒泡排序算法詳見(jiàn)程序清單3.56

程序清單3.56冒泡排序算法函數(shù)

1 void iter_sort(iterator_if_t *p_if, iterator_t begin, iterator_t end, compare_t compare, swap_t swap)

2 {

3 int flag = 1; // flag = 1,表示指針的內(nèi)容未交換

4 iterator_t it1 = begin; // it1指向數(shù)組變量的首元素

5 iterator_t it2 = end;

6

7 iterator_t it_next; // pNext指向p1所指向的元素的下一個(gè)元素

8 if (begin == end) { //沒(méi)有需要算法處理的迭代器

9 return;

10 }

11 iterator_prev(p_if, &it2); // it2指向需要排序的最后一個(gè)元素

12 while (it2 != begin){

13 it1 = begin;

14 flag = 1;

15 while(it1 != it2){

16 it_next = it1; //暫存

17 iterator_next(p_if, &it_next); // it_next為 it1 的下一個(gè)元素

18 if(compare(it1, it_next) > 0){

19 swap(it1, it_next); //交換內(nèi)容

20 flag = 0; // flag = 0,表示指針的內(nèi)容已交換

21 }

22 it1 = it_next; // it1的下一個(gè)元素

23 }

24 if(flag) return; //沒(méi)有交換,表示已經(jīng)有序,則直接返回

25 iterator_prev(p_if, &it2); // it2向前移

26 }

27 }

下面以一個(gè)簡(jiǎn)單的例子來(lái)測(cè)試驗(yàn)證基于迭代器的冒泡排序算法,詳見(jiàn)程序清單3.57。將整數(shù)存放到雙向鏈表中,首先將5、4、3、2、1分別加在鏈表的尾部,接著調(diào)用dlist_foreach()遍歷鏈表,看是否符合預(yù)期,然后再調(diào)用算法庫(kù)的iter_sort()排序。當(dāng)排序完畢后鏈表的元素應(yīng)該是從小到大排列的,再次調(diào)用算法庫(kù)的dilst_foreach()遍歷鏈表,看是否符合預(yù)期。

程序清單3.57使用雙向鏈表、算法和迭代器

1 #include

2 #include "iterator.h"

3

4 typedef struct _dlist_int{

5 dlist_node_t node; //包含鏈表結(jié)點(diǎn)

6 int data; // int類(lèi)型數(shù)據(jù)

7 }dlist_int_t;

8

9 int list_node_process(void *p_arg, dlist_node_t *p_node)

10 {

11 printf("%d ", ((dlist_int_t *)p_node) -> data);

12 return 0;

13 }

14

15 static int __compare(iterator_t it1, iterator_t it2)

16 {

17 return ((dlist_int_t *)it1) -> data - ((dlist_int_t *)it2) -> data;

18 }

19

20 static void __swap(iterator_t it1, iterator_t it2)

21 {

22 int data = ((dlist_int_t *)it2) -> data;

23 ((dlist_int_t *)it2) -> data = ((dlist_int_t *)it1) -> data;

24 ((dlist_int_t *)it1) -> data = data;

25 }

26

27 int main(int argc, char *argv[])

28 {

29 iterator_if_t iterator_if;

30 dlist_head_t head; //定義鏈表頭結(jié)點(diǎn)

31 dlist_int_t node[5]; //定義5個(gè)結(jié)點(diǎn)空間

32 int i;

33

34 dlist_init(&head);

35

36 for (i = 0; i < 5; i++) {? ???????????????????????? //?將5個(gè)結(jié)點(diǎn)添加至鏈表尾部

37 node[i].data = 5 - i; //使值的順序?yàn)?5 ~ 1

38 dlist_add_tail(&head, &(node[i].node));

39 }

40 dlist_iterator_if_get(&iterator_if);

41

42 printf("\nBefore bubble sort:\n");

43 dlist_foreach (&head, list_node_process, NULL); //打印排序前的情況

44

45 iter_sort(&iterator_if, dlist_begin_get(&head), dlist_end_get(&head),__compare, __swap);

46

47 printf("\nAfter bubble sort:\n");

48 dlist_foreach (&head, list_node_process, NULL); //打印排序后的情況

49 return 0;

50 }

在這里,使用了dlist_foreach()遍歷函數(shù),既然通過(guò)迭代器能夠?qū)崿F(xiàn)冒泡排序,那么也能通過(guò)迭代器實(shí)現(xiàn)簡(jiǎn)單的遍歷算法,此時(shí)遍歷算法與具體容器無(wú)關(guān)。遍歷函數(shù)的原型如下

void iter_foreach(iterator_if_t *p_if, iterator_t begin, iterator_t end, visit_t visit, void *p_arg);

其中,p_if表示算法使用的迭代器接口,begin與end表示算法需要處理的迭代器范圍,visit是用戶(hù)自定義的遍歷迭代器的函數(shù)。其類(lèi)型visit_t定義如下:

typedef int (*visit_t)(void *p_arg, iterator_t it);

visit_t參數(shù)p_arg指針和it迭代器,其返回值為int類(lèi)型的函數(shù)指針。每遍歷一個(gè)結(jié)點(diǎn)均會(huì)調(diào)用visit指向的函數(shù),傳遞給p_arg的值即為用戶(hù)參數(shù),其值為iter_foreach()函數(shù)的p_arg參數(shù),p_arg的值完全是由用戶(hù)決定的,傳遞給it迭代器的值即為指向當(dāng)前遍歷的迭代器,iter_foreach()函數(shù)的實(shí)現(xiàn)詳見(jiàn)程序清單3.58

程序清單3.58遍歷算法函數(shù)

1 void iter_foreach(iterator_if_t *p_if, iterator_t begin, iterator_t end, visit_t visit, void *p_arg)

2 {

3 iterator_t it = begin;

4 while(it != end){

5 if (visit(p_arg, it) < 0) {???? ?????????????????? //?若返回值為負(fù)值,表明用戶(hù)終止了遍歷

6 return;

7 }

8 iterator_next(p_if, &it); //讓迭代器向后移動(dòng)

9 }

10 }

現(xiàn)在可以將程序清單3.57的第43行和第48行中的dlist_foreach()函數(shù)修改為使用iter_foreach()函數(shù),看能否得到相同的效果?

如果將數(shù)據(jù)保存在數(shù)組變量中,那么將如何使用已有的冒泡排序算法呢?由于數(shù)組也是容器,因此只要實(shí)現(xiàn)基于數(shù)組的迭代器即可,詳見(jiàn)程序清單3.59。

程序清單3.59使用數(shù)組實(shí)現(xiàn)迭代器接口

1 typedef int element_type_t;

2

3 static void __array_iterator_next(iterator_t *p_iter)

4 {

5 (*(element_type_t **)(p_iter))++; //讓迭代器指向下一個(gè)數(shù)據(jù)

6 }

7

8 static void __array_iterator_prev(iterator_t *p_iter)

9 {

10 (*(element_type_t **)(p_iter))--; //讓迭代器指向前一個(gè)數(shù)據(jù)

11 }

12

13 void array_iterator_if_get(iterator_if_t *p_if)

14 {

15 iterator_if_init(p_if, __array_iterator_next, __array_iterator_prev);

16 }

基于新的迭代器,同樣可以直接使用冒泡排序算法實(shí)現(xiàn)排序,詳見(jiàn)程序清單3.60。

程序清單3.60使用數(shù)組、算法和迭代器

1 #include

2 #include "iterator.h"

3

4 static int __visit(void *p_arg, iterator_t it)

5 {

6 printf("%d ", *(int *)it);

7 return 0;

8 }

9

10 static int __compare(iterator_t it1, iterator_t it2)

11 {

12 return *(int *)it1 - *(int *)it2;

13 }

14

15 static void __swap(iterator_t it1, iterator_t it2)

16 {

17 int data = *(int *)it2;

18 *(int *)it2 = *(int *)it1;

19 *(int *)it1 = data;

20 }

21

22 int main(int argc, char *argv[])

23 {

24 iterator_if_t iterator_if;

25 int a[] = {5, 3, 2, 4, 1};

26 array_iterator_if_get(&iterator_if);

27

28 printf("\nBefore bubble sort:\n");

29 iter_foreach(&iterator_if, a, a + 5, __visit, NULL);

30

31 iter_sort(&iterator_if, a, a + 5, __compare, __swap);

32

33 printf("\nAfter bubble sort:\n");

34 iter_foreach(&iterator_if, a, a + 5, __visit, NULL);

35 return 0;

36 }

由此可見(jiàn),通過(guò)迭代器冒泡排序算法也得到了復(fù)用。如果算法庫(kù)里有幾百個(gè)函數(shù),那么只要實(shí)現(xiàn)迭代器接口的2個(gè)函數(shù)即可,從而達(dá)到復(fù)用代碼的目的。顯然,迭代器是一種更靈活的遍歷行為,它可以按任意順序訪問(wèn)容器中的元素,而且不會(huì)暴露容器的內(nèi)部結(jié)構(gòu)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4552

    瀏覽量

    92021
  • 指針
    +關(guān)注

    關(guān)注

    1

    文章

    475

    瀏覽量

    70457
  • 周立功
    +關(guān)注

    關(guān)注

    38

    文章

    130

    瀏覽量

    37438
  • 迭代器
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    4289

原文標(biāo)題:周立功:迭代器——算法的接口

文章出處:【微信號(hào):Zlgmcu7890,微信公眾號(hào):周立功單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Python高級(jí)特性:迭代切片的應(yīng)用

    在前兩篇關(guān)于 Python 切片的文章中,我們學(xué)習(xí)了切片的基礎(chǔ)用法、高級(jí)用法、使用誤區(qū),以及自定義對(duì)象如何實(shí)現(xiàn)切片用法(相關(guān)鏈接見(jiàn)文末)。本文是切片系列的第三篇,主要內(nèi)容是迭代切片。 迭代
    發(fā)表于 11-29 10:11 ?627次閱讀

    labview迭代實(shí)現(xiàn)方法

    請(qǐng)問(wèn)一下,那位高手知道labview怎樣實(shí)現(xiàn)迭代?。??
    發(fā)表于 03-27 14:00

    請(qǐng)問(wèn)迭代實(shí)現(xiàn)原理是什么?

    什么是集合框架?LIST接口的實(shí)際應(yīng)用?迭代實(shí)現(xiàn)原理是什么?
    發(fā)表于 11-04 09:45

    阻容相橋觸發(fā)電路是如何實(shí)現(xiàn)相的

    阻容相橋觸發(fā)電路是如何實(shí)現(xiàn)相的?單穩(wěn)態(tài)電路的輸出脈沖寬度取決于什么?什么是電阻測(cè)量法?直接耦合放大電路的特點(diǎn)是什么?
    發(fā)表于 08-19 07:54

    什么是void指針?void指針有何功能

    一般被稱(chēng)為通用指針叫泛指針。它是C語(yǔ)言關(guān)于純粹地址的一種約定。當(dāng)某個(gè)指針是void型指針時(shí),所指向的對(duì)象不屬于任何類(lèi)型。 因?yàn)関oid
    發(fā)表于 02-21 06:01

    python迭代

    確的方法,還是應(yīng)該使用 for 循環(huán)。3. 可迭代協(xié)議可迭代對(duì)象內(nèi)部是如何實(shí)現(xiàn)在你對(duì)其進(jìn)行 for 循環(huán)時(shí),可以一個(gè)一個(gè)元素的返回出來(lái)呢?這就要談到迭代
    發(fā)表于 02-24 15:42

    OpenHarmony中的HDF單鏈表及其迭代

    of it. */struct HdfSListNode *HdfSListIteratorNext(struct HdfSListIterator *iterator);迭代實(shí)現(xiàn)考慮對(duì)于本文所描述的單鏈表
    發(fā)表于 08-30 10:31

    OpenHarmony中的HDF單鏈表及其迭代

    */structHdfSListNode*HdfSListIteratorNext(structHdfSListIterator*iterator);迭代實(shí)現(xiàn)考慮對(duì)于本文所描述的單鏈表迭代
    發(fā)表于 09-05 11:38

    人工智能抗疫 AI技術(shù)實(shí)現(xiàn)了篩查的時(shí)間窗口

    人工智能(AI)在本次新冠肺炎疫情的防控中得到了實(shí)際應(yīng)用,涵蓋了輔助診斷、影像分析、藥物研發(fā)、體溫檢測(cè)、醫(yī)療機(jī)器人等多個(gè)AI+醫(yī)療領(lǐng)域。尤其是在主戰(zhàn)場(chǎng)AI醫(yī)學(xué)影像方面,AI技術(shù)實(shí)現(xiàn)了篩查的時(shí)間窗口。
    發(fā)表于 02-27 10:42 ?702次閱讀

    理解函數(shù)指針、函數(shù)指針數(shù)組、函數(shù)指針數(shù)組的指針

    理解函數(shù)指針、函數(shù)指針數(shù)組、函數(shù)指針數(shù)組的指針
    的頭像 發(fā)表于 06-29 15:38 ?1.5w次閱讀
    理解函數(shù)<b class='flag-5'>指針</b>、函數(shù)<b class='flag-5'>指針</b>數(shù)組、函數(shù)<b class='flag-5'>指針</b>數(shù)組的<b class='flag-5'>指針</b>

    【C和指針指針

    指針的概念:說(shuō)的實(shí)用一點(diǎn),指針就是地址。包括對(duì)指針的各種操作,就是對(duì)地址和變量之間的互相轉(zhuǎn)換等操作(個(gè)人理解);地址的概念:計(jì)算機(jī)的內(nèi)存都是由0和1組成的。由于0和1只能表示兩種情況。所以在使用時(shí)
    發(fā)表于 01-13 15:51 ?1次下載
    【C和<b class='flag-5'>指針</b>】<b class='flag-5'>指針</b>

    什么是迭代?

    對(duì)于int型數(shù)組除了用下標(biāo)訪問(wèn),還可以通過(guò)指針訪問(wèn),實(shí)際上迭代就是對(duì)指針進(jìn)行了封裝。
    的頭像 發(fā)表于 02-27 15:55 ?1560次閱讀
    什么是<b class='flag-5'>迭代</b><b class='flag-5'>器</b>?

    Python中的迭代介紹 迭代在scoreboard中的應(yīng)用有哪些?

    Iterator Design Pattern: 對(duì)容器 (聚合類(lèi),集合數(shù)據(jù)等) 的遍歷操作從容器中拆分出來(lái),放到迭代中,實(shí)現(xiàn)迭代操作的解耦。
    的頭像 發(fā)表于 08-08 09:41 ?524次閱讀
    Python中的<b class='flag-5'>迭代</b><b class='flag-5'>器</b>介紹 <b class='flag-5'>迭代</b><b class='flag-5'>器</b>在scoreboard中的應(yīng)用有哪些?

    C++智能指針的底層實(shí)現(xiàn)原理

    C++智能指針的頭文件: #include 1. shared_ptr: 智能指針從本質(zhì)上來(lái)說(shuō)是一個(gè)模板類(lèi),用類(lèi)實(shí)現(xiàn)對(duì)指針對(duì)象的管理。 template class shared_pt
    的頭像 發(fā)表于 11-09 14:32 ?573次閱讀
    C++智能<b class='flag-5'>指針</b>的底層<b class='flag-5'>實(shí)現(xiàn)</b>原理

    從概念到應(yīng)用 終于有人把式無(wú)人叉車(chē)講明白了 趕緊收藏

    ,又稱(chēng)無(wú)人駕駛式叉車(chē)式叉車(chē)AGV,是一種能夠自主導(dǎo)航、裝卸、堆垛和短距離運(yùn)輸成件托盤(pán)貨物的智能設(shè)備。其特點(diǎn)主要包括:? 貨叉
    的頭像 發(fā)表于 08-22 11:13 ?170次閱讀
    從概念到應(yīng)用 終于有人把<b class='flag-5'>前</b><b class='flag-5'>移</b>式無(wú)人叉車(chē)講明白了 趕緊收藏