1 / 73

第十二讲 : 排序实现 、 多维数组

第十二讲 : 排序实现 、 多维数组. 北京大学 信息科学技术学院 20 12 年 11 月. 利用 数组 , 对一组数据 进行排序. 冒泡排序法 选择排序法 归并排序法. 如何把大象关在冰箱里 ?. 排序的基本方法. 分3步: 第一步: 打开冰箱门 ; 第二步: 把大象推进冰箱 ; 第三步: 关上冰箱门 ;. int sz [ LEN ]; // #define LEN 8. 排序的基本方法. 7. 11. 18. 6. 12. 17. 分8个步骤进行 第 1 步:把 第1大 的数放在变量 sz[7] 中;

hammer
Download Presentation

第十二讲 : 排序实现 、 多维数组

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第十二讲:排序实现、多维数组 北京大学信息科学技术学院 2012年11月

  2. 利用数组,对一组数据进行排序 冒泡排序法 选择排序法 归并排序法

  3. 如何把大象关在冰箱里? 排序的基本方法 • 分3步: • 第一步:打开冰箱门; • 第二步:把大象推进冰箱; • 第三步:关上冰箱门;

  4. int sz[LEN]; //#define LEN8 排序的基本方法 7 11 18 6 12 17 • 分8个步骤进行 • 第1步:把第1大的数放在变量sz[7]中; • 第2步:把第2大的数放在变量sz[6]中; • 第3步:把第3大的数放在变量sz[5]中; • 第4步:把第4大的数放在变量sz[4]中; • 第5步:把第5大的数放在变量sz[3]中; • 第6步:把第6大的数放在变量sz[2]中; • 第7步:把第7大的数放在变量sz[1]中; • 第8步:把第8大的数放在变量sz[0]中; 5 13 16 4 17 15 3 18 14 2 14 13 1 15 12 0 16 11 编号 排序前 的值 排序后 的值

  5. 排序的基本方法 int sz[LEN]; //#define LEN8 • 分8个步骤进行 • 第1步:把第1大的数放在变量sz[7]中; • 第2步:把第2大的数放在变量sz[6]中; • 第3步:把第3大的数放在变量sz[5]中; • 第4步:把第4大的数放在变量sz[4]中; • 第5步:把第5大的数放在变量sz[3]中; • 第6步:把第6大的数放在变量sz[2]中; • 第7步:把第7大的数放在变量sz[1]中; • 第8步:把第8大的数放在变量sz[0]中; • 分LEN个步骤进行 • 第1步:把第1大的数放在变量sz[LEN-1]中; • 第2步:把第2大的数放在变量sz[LEN-2]中; • 第3步:把第3大的数放在变量sz[LEN-3]中; • 第4步:把第4大的数放在变量sz[LEN-4]中; • 第5步:把第5大的数放在变量sz[LEN-5]中; • 第6步:把第6大的数放在变量sz[LEN-6]中; • …… • 第LEN步:把第LEN大的数放在变量sz[0]中;

  6. 排序的基本方法 • 分LEN个步骤进行 • 第1步:把第1大的数放在变量sz[LEN-1]中; • 第2步:把第2大的数放在变量sz[LEN-2]中; • 第3步:把第3大的数放在变量sz[LEN-3]中; • 第4步:把第4大的数放在变量sz[LEN-4]中; • 第5步:把第5大的数放在变量sz[LEN-5]中; • 第6步:把第6大的数放在变量sz[LEN-6]中; • …… • 第LEN步:把第LEN大的数放在变量sz[0]中;

  7. 排序的基本方法 对数组intsz[LEN]进行排序, 可以分为LEN 个步骤进行。 第k步:把第k 大的数放在变量 sz[LEN-k] 中; (K=1, 2, 3, 4, …, LEN-1, LEN)

  8. 用冒泡法作第1步: 把第1大的数放在变量sz[LEN-1]中; int e; for(int i = 0; i < LEN - 1; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  9. 用冒泡法作第2步: 把第2大的数放在变量sz[LEN-2]中; int e; for(int i = 0; i < LEN - 2; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  10. 用冒泡法作第3步: 把第3大的数放在变量sz[LEN-3]中; int e; for(int i = 0; i < LEN - 3; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  11. 用冒泡法作第k步: 把第k大的数放在变量sz[LEN-k]中; int e; for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  12. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  13. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  14. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } }

  15. 用冒泡法对数组intsz[LEN]进行排序 int e; for(;;){ for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } } }

  16. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int k = ; k <= ; k++){ for(inti= 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } } }

  17. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int k = 1 ; k <= ; k++){ for(inti= 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } } }

  18. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int k = 1 ; k <= LEN ; k++){ for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } } }

  19. 用冒泡法对数组intsz[LEN]进行排序 int e; for(int k = 1 ; k <= LEN ; k++){ for(int i = 0; i < LEN - k; i++){ if(sz[i] >sz[i+1]){ e = sz[i+1]; sz[i+1] = sz[i]; sz[i] = e; } } } 对该算法进行测试 编写一个程序: 1.从控制台输入一组 数据,并将其存放 一个数组中; 2.用左侧算法进行排 序; 3.打印出排序结果;

  20. 选择排序法

  21. 排序的基本方法 对数组intsz[LEN]进行排序, 可以分为LEN 个步骤进行。 第k步:把第k 大的数放在变量 sz[LEN-k] 中; (K=1, 2, 3, 4, …, LEN-1, LEN)

  22. 用选择法作第1步:把第1大的数放在变量sz[LEN-1]中;用选择法作第1步:把第1大的数放在变量sz[LEN-1]中; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-1; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-1){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-1]; sz[LEN-1] = e; }

  23. 用选择法作第2步:把第2大的数放在变量sz[LEN-2]中;用选择法作第2步:把第2大的数放在变量sz[LEN-2]中; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-2; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-2){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-2]; sz[LEN-2] = e; }

  24. 用选择法作第3步:把第3大的数放在变量sz[LEN-3]中;用选择法作第3步:把第3大的数放在变量sz[LEN-3]中; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-3; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-3){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-3]; sz[LEN-3] = e; }

  25. 用选择法作第k步:把第k大的数放在变量sz[LEN-k]中;用选择法作第k步:把第k大的数放在变量sz[LEN-k]中; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; }

  26. 用选择法对数组intsz[LEN]进行排序; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; }

  27. 用选择法对数组intsz[LEN]进行排序; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; }

  28. 用选择法对数组intsz[LEN]进行排序; int maxIndex, e; maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; }

  29. 用选择法对数组intsz[LEN]进行排序; int maxIndex, e; for(;;){ maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; } }

  30. 用选择法对数组intsz[LEN]进行排序; intmaxIndex, e; for(int k = ; k <= ; k++){ maxIndex= 0; for(inti= 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex= i; } } if(maxIndex!= LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; } }

  31. 用选择法对数组intsz[LEN]进行排序; int maxIndex, e; for(int k = 1 ; k <= LEN; k++){ maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; } }

  32. 用选择法对数组intsz[LEN]进行排序; int maxIndex, e; for(int k = 1 ; k <= LEN; k++){ maxIndex = 0; for(int i = 0; i <= LEN-k; i++){ if(sz[i] >sz[maxIndex]){ maxIndex = i; } } if(maxIndex != LEN-k){ e = sz[maxIndex]; sz[maxIndex] = sz[LEN-k]; sz[LEN-k] = e; } } 对该算法进行测试 编写一个程序: 1.从控制台输入一组 数据,并将其存放 一个数组中; 2.用左侧算法进行排 序; 3.打印出排序结果;

  33. 归并排序法

  34. 归并排序的思想 • 如果只有一个数,则已经排好序,结束; • 递归的把前一半数排好序; • 递归的把后一半数排好序; • 把前后两个排好序的部分按序合并在一起。

  35. 归并排序示例 1 4 2 7 3 5 8 6

  36. 归并排序示例 1 4 2 7 3 5 8 6 把数组分为前后两部分

  37. 归并排序示例 1 2 4 7 3 5 6 8 递归的把前半部分排好序 递归的把后半部分排好序

  38. 归并排序示例 1 2 4 7 3 5 6 8 再把两部分归并到一起

  39. 归并排序示例 1 2 4 7 3 5 6 8

  40. 归并排序示例 1 2 4 7 3 5 6 8 1

  41. 归并排序示例 1 2 4 7 3 5 6 8 1 2

  42. 归并排序示例 1 2 4 7 3 5 6 8 1 2 3

  43. 归并排序示例 1 2 4 7 3 5 6 8 1 2 3 4

  44. 归并排序示例 1 2 4 7 3 5 6 8 1 2 3 4 5

  45. 归并排序示例 1 2 4 7 3 5 6 8 1 2 3 4 5 6

  46. 归并排序示例 1 2 4 7 3 5 6 8 1 2 3 4 5 6 7

  47. 归并排序示例 1 2 4 7 3 5 6 8 1 2 3 4 5 6 7 8

  48. #include <stdio.h> • #define MAX 1000/* 最大数组大小 */ • voidmerge_sort(inta[], intfrom, intto); /* 函数声明 */ • intmain() • { • inta[MAX]; /* 定义数组 */ • inti, n; • scanf("%d", &n); /* 读入数的个数 */ • for (i = 0; i < n; i++) { /* 把数读入数组 */ • scanf("%d", &a[i]); • } • merge_sort(a, 0, n); /* 调用归并排序函数 */ • for (i = 0; i < n; i++) { /* 把排好序的数输出 */ • printf("%d\n", a[i]); • } • return 0; • }

  49. /* 合并函数声明,将数组a中排好序的两个部分合并 */ voidmerge(inta[], intfrom, intmid, intto); /* 归并排序函数,递归的将数组a中从from到to间的数排序 */ voidmerge_sort(inta[], intfrom, intto) { if ((to - from) == 1) /* 如果只有一个数,直接返回 */ return; intmid = (from + to) / 2;/* 计算中间点位置 */ merge_sort(a, from, mid); /* 递归的排序前半部分 */ merge_sort(a, mid, to); /* 递归的排序后半部分 */ merge(a, from, mid, to); /* 将前后两部分归并到数组a中 */ }

  50. intt[MAX];/* 全局临时数组,用于暂存合并结果 */ /* 合并函数声明,将数组a中排好序的两个部分合并 */ void merge(inta[], intfrom, intmid, intto) { inti = from, j = mid, k = from; while (i < mid && j < to) { /* 两部分都还有剩余的数 */ if (a[i] < a[j]) { t[k++] = a[i++]; /* 前半部分的当前数更小,复制到目标数组 */ } else { t[k++] = a[j++]; /* 后半部分的当前数更小,复制到目标数组 */ } } while (i < mid) { /* 只有前半部分都还有剩余的数 */ t[k++] = a[i++]; /* 把剩余的数复制到目标数组 */ } while (j < to) { /* 只有后半部分都还有剩余的数 */ t[k++] = a[j++]; /* 把剩余的数复制到目标数组 */ } for (i = from; i < to; i++) { /* 把归并结果复制到数组t中 */ a[i] = t[i]; } }

More Related