在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用迭代器如何實現指針前移或后移

UtFs_Zlgmcu7890 ? 來源:互聯網 ? 作者:佚名 ? 2017-09-27 14:06 ? 次閱讀

近日周立功教授公開了數年的心血之作《程序設計與數據結構》,電子版已無償性分享到電子工程師與高校群體下載,經周立功教授授權,特對本書內容進行連載。

>>>>1.1.1 算法接口

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

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

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

compare同樣也是比較函數,但比較的類型發生了變化,用于比較兩個迭代器所對應的值。其類型compare_t定義如下:

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

swap函數用于交換兩個迭代器所對應的數據,其類型swap_t定義如下:

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

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

程序清單3.56冒泡排序算法函數

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,表示指針的內容未交換

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

5 iterator_t it2 = end;

6

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

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

9 return;

10 }

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

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 的下一個元素

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

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

20 flag = 0; // flag = 0,表示指針的內容已交換

21 }

22 it1 = it_next; // it1的下一個元素

23 }

24 if(flag) return; //沒有交換,表示已經有序,則直接返回

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

26 }

27 }

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

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

1 #include

2 #include "iterator.h"

3

4 typedef struct _dlist_int{

5 dlist_node_t node; //包含鏈表結點

6 int data; // int類型數據

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; //定義鏈表頭結點

31 dlist_int_t node[5]; //定義5個結點空間

32 int i;

33

34 dlist_init(&head);

35

36 for (i = 0; i < 5; i++) {? ???????????????????????? //?將5個結點添加至鏈表尾部

37 node[i].data = 5 - i; //使值的順序為 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()遍歷函數,既然通過迭代器能夠實現冒泡排序,那么也能通過迭代器實現簡單的遍歷算法,此時遍歷算法與具體容器無關。遍歷函數的原型如下

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是用戶自定義的遍歷迭代器的函數。其類型visit_t定義如下:

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

visit_t的參數是p_arg指針和it迭代器其返回值為int類型的函數指針。每遍歷一個結點均會調用visit指向的函數,傳遞給p_arg的值即為用戶參數,其值為iter_foreach()函數的p_arg參數,p_arg的值完全是由用戶決定的,傳遞給it迭代器的值即為指向當前遍歷的迭代器iter_foreach()函數的實現詳見程序清單3.58

程序清單3.58遍歷算法函數

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) {???? ?????????????????? //?若返回值為負值表明用戶終止了遍歷

6 return;

7 }

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

9 }

10 }

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

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

程序清單3.59使用數組實現迭代器接口

1 typedef int element_type_t;

2

3 static void __array_iterator_next(iterator_t *p_iter)

4 {

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

6 }

7

8 static void __array_iterator_prev(iterator_t *p_iter)

9 {

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

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 }

基于新的迭代器同樣可以直接使用冒泡排序算法實現排序,詳見程序清單3.60

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

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 }

由此可見,通過迭代器冒泡排序算法也得到了復用。如果算法庫里有幾百個函數,那么只要實現迭代器接口的2個函數即可,從而達到復用代碼的目的。顯然,迭代器是一種更靈活的遍歷行為,它可以按任意順序訪問容器中的元素,而且不會暴露容器的內部結構。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4681

    瀏覽量

    94323
  • 指針
    +關注

    關注

    1

    文章

    484

    瀏覽量

    70896
  • 周立功
    +關注

    關注

    38

    文章

    130

    瀏覽量

    38028
  • 迭代器
    +關注

    關注

    0

    文章

    45

    瀏覽量

    4426

原文標題:周立功:迭代器——算法的接口

文章出處:【微信號:Zlgmcu7890,微信公眾號:周立功單片機】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Python高級特性:迭代切片的應用

    在前兩篇關于 Python 切片的文章中,我們學習了切片的基礎用法、高級用法、使用誤區,以及自定義對象如何實現切片用法(相關鏈接見文末)。本文是切片系列的第三篇,主要內容是迭代切片。 迭代
    發表于 11-29 10:11 ?759次閱讀

    labview迭代實現方法

    請問一下,那位高手知道labview怎樣實現迭代!!?
    發表于 03-27 14:00

    請問迭代實現原理是什么?

    什么是集合框架?LIST接口的實際應用?迭代實現原理是什么?
    發表于 11-04 09:45

    阻容相橋觸發電路是如何實現相的

    阻容相橋觸發電路是如何實現相的?單穩態電路的輸出脈沖寬度取決于什么?什么是電阻測量法?直接耦合放大電路的特點是什么?
    發表于 08-19 07:54

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

    一般被稱為通用指針叫泛指針。它是C語言關于純粹地址的一種約定。當某個指針是void型指針時,所指向的對象不屬于任何類型。 因為void
    發表于 02-21 06:01

    python迭代

    確的方法,還是應該使用 for 循環。3. 可迭代協議可迭代對象內部是如何實現在你對其進行 for 循環時,可以一個一個元素的返回出來呢?這就要談到迭代
    發表于 02-24 15:42

    OpenHarmony中的HDF單鏈表及其迭代

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

    OpenHarmony中的HDF單鏈表及其迭代

    */structHdfSListNode*HdfSListIteratorNext(structHdfSListIterator*iterator);迭代實現考慮對于本文所描述的單鏈表迭代
    發表于 09-05 11:38

    人工智能抗疫 AI技術實現了篩查的時間窗口

    人工智能(AI)在本次新冠肺炎疫情的防控中得到了實際應用,涵蓋了輔助診斷、影像分析、藥物研發、體溫檢測、醫療機器人等多個AI+醫療領域。尤其是在主戰場AI醫學影像方面,AI技術實現了篩查的時間窗口
    發表于 02-27 10:42 ?829次閱讀

    理解函數指針、函數指針數組、函數指針數組的指針

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

    【C和指針指針

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

    什么是迭代

    對于int型數組除了用下標訪問,還可以通過指針訪問,實際上迭代就是對指針進行了封裝。
    的頭像 發表于 02-27 15:55 ?2239次閱讀
    什么是<b class='flag-5'>迭代</b><b class='flag-5'>器</b>?

    Python中的迭代介紹 迭代在scoreboard中的應用有哪些?

    Iterator Design Pattern: 對容器 (聚合類,集合數據等) 的遍歷操作從容器中拆分出來,放到迭代中,實現迭代操作的解耦。
    的頭像 發表于 08-08 09:41 ?746次閱讀
    Python中的<b class='flag-5'>迭代</b><b class='flag-5'>器</b>介紹 <b class='flag-5'>迭代</b><b class='flag-5'>器</b>在scoreboard中的應用有哪些?

    C++智能指針的底層實現原理

    C++智能指針的頭文件: #include 1. shared_ptr: 智能指針從本質上來說是一個模板類,用類實現指針對象的管理。 template class shared_pt
    的頭像 發表于 11-09 14:32 ?928次閱讀
    C++智能<b class='flag-5'>指針</b>的底層<b class='flag-5'>實現</b>原理

    從概念到應用 終于有人把式無人叉車講明白了 趕緊收藏

    ,又稱無人駕駛式叉車式叉車AGV,是一種能夠自主導航、裝卸、堆垛和短距離運輸成件托盤貨物的智能設備。其特點主要包括:? 貨叉
    的頭像 發表于 08-22 11:13 ?608次閱讀
    從概念到應用 終于有人把<b class='flag-5'>前</b><b class='flag-5'>移</b>式無人叉車講明白了 趕緊收藏
    主站蜘蛛池模板: 兔费看全黄三级 | 朱元璋传奇1998王耿豪版 | 三级黄色片免费观看 | 五月天婷婷久久 | 99国产成人精品2021 | 免费的色视频 | 国产又粗又大又爽又免费 | 五月天婷婷在线视频 | 高h上错人1v1 | 亚洲成a人片777777久久 | 日日干夜夜操s8 | 免费观看视频在线 | 国产伦精品一区二区三区免费 | 影音先锋在线亚洲精品推荐 | 男啪女r18肉车文 | 欧美xx高清 | 亚洲男人天堂网址 | 天天操夜夜操免费视频 | 国产精品久久久久久久久免费观看 | 婷婷久久综合网 | 久久精品国产99国产精品澳门 | 亚洲成a人不卡在线观看 | 五月婷婷综合色 | 四虎影视大全免费入口 | 精品欧美| 秋霞一级特黄真人毛片 | 色婷婷六月丁香七月婷婷 | 天堂在线免费 | 亚洲国产精品婷婷久久 | 九色在线播放 | 国产精品igao在线观看樱花日本 | 大学生一级特黄的免费大片视频 | 美女被网站免费看九色视频 | 国产精品亚洲四区在线观看 | 婷婷九月 | 国产色婷婷精品免费视频 | 9久久99久久久精品齐齐综合色圆 | 在线观看亚洲免费视频 | 欧美一区二区三区不卡视频 | 一级a爱片久久毛片 | 亚洲日本在线观看 |