180 likes | 512 Views
第八讲 排序算法. 主要内容. 最小排序 插入排序 希尔( Shell )排序 冒泡排序 快速排序. 一、最小排序. 最小排序: 找出最小值,将其与第一个位置的元素交换,然后对剩余的序列重复以上过程,直至排序结束。. 原始数列: 2 8 3 12 5 20 7 14 5 16 第1次排序: 2 8 3 12 5 20 7 14 5 16 第2次排序: 2 3 8 12 5 20 7 14 5 16
E N D
主要内容 • 最小排序 • 插入排序 • 希尔(Shell)排序 • 冒泡排序 • 快速排序
一、最小排序 • 最小排序:找出最小值,将其与第一个位置的元素交换,然后对剩余的序列重复以上过程,直至排序结束。 原始数列: 2 8 3 12 5 20 7 14 5 16 第1次排序:2 8 3 12 5 20 7 14 5 16 第2次排序:2 3 8 12 5 20 7 14 5 16 第3次排序:2 3 5 12 8 20 7 14 5 16 第4次排序:2 3 5 5 8 20 7 14 12 16 第5次排序:2 3 5 5 7 20 8 14 12 16 第6次排序:2 3 5 5 7 8 20 14 12 16 第7次排序:2 3 5 5 7 8 12 14 20 16 第8次排序:2 3 5 5 7 8 12 14 20 16 第9次排序:2 3 5 5 7 8 12 14 16 20
Matlab 程序 • 最小排序 Matlab 程序 % 最小排序 Matlab 程序 function x = Sort_min(x,n) for k = 1 : n % 找出未排序部分的最小值及其所在位置 [xmin, ind] = min(x(k:n)); t = x(k); % 交换 x(k) = x(k+ind-1); x(k+ind-1) = t; end
C++程序 • 最小排序 C++ 程序 // 找出最小值所在的位置 int my_min(int *px, int n) { int idx=0, xmin=*px; for (int i=1; i<n; i++) if (*(px+i)<xmin) { xmin = *(px+i); idx=i; } return idx; } // 最小排序 void Sort_min(int *px, int n) { int idx, t; for(int k=0; k<n ; k++) { idx = my_min(px+k,n-k); t=px[k]; px[k]=px[k+idx]; px[k+idx]=t;% 交换 } }
二、插入排序 • 插入排序:假设前面 k 个元素已经按顺序排好了,在排第 k+1 个数时,将其插入到前面已排好的 k 个数中,使得插入后得到的 k+1 个数组成的序列仍按值有序。如此下去直到遍历完序列的所有元素为止。 原始数列: 2 8 3 12 5 20 7 14 5 16 第1次排序:28 3 12 5 20 7 14 5 16 第2次排序:238 12 5 20 7 14 5 16 第3次排序:2 3 8 12 5 20 7 14 5 16 第4次排序:2 3 5 8 12 20 7 14 5 16 第5次排序:2 3 5 8 12 20 7 14 5 16 第6次排序:2 3 5 7 8 12 20 14 5 16 第7次排序:2 3 5 7 8 12 14 20 5 16 第8次排序:2 3 5 5 7 8 12 14 20 16 第9次排序:2 3 5 5 7 8 12 14 16 20
Matlab 程序 % 插入排序 Matlab 程序 function x = Sort_Insert(x,n) for k = 1 : n-1 key = x(k+1); % 需要插入的元素 i = k; while ( i > 0 && x(i) > key) % 将前面 k 个元素中大于 x(k+1) 的数据向后移动 x(i+1) = x(i); i = i - 1; end x(i+1) = key; % 将当前元素插入合适的位置 end
三、希尔(Shell)排序 • Shell 排序:又称为“缩小增量排序”(Diminishing Increment Sort),由 Donald Shell 在1959年提出,是对插入排序的一个改进。它每次排序时把序列按照某个增量分成几个子序列,对这几个子序列进行插入排序,然后不断的缩小增量扩大每个子序列的元素数量,直到增量为 1 的时候,子序列就和原先的待排列序列一样了,而此时序列基本上已经排序好了,因此只需要做少量的比较和移动就可以完成对序列的排序。
Matlab 程序 % 希尔(shell)排序Matlab程序 function x = Sort_Shell(x,n) step = floor(n/2); % 增量从数组长度的一半开始,每次减小一倍 while step > 0 for k = step + 1 : n key = x(k); % 需要插入的元素 i = k-step; % 对一组增量为step的元素进行插入排序 while ( i > 0 && x(i) > key) x(i+step) = x(i); i = i - step; end x(i+step) = key; % 将当前元素插入合适的位置 end step = floor(step/2); end
四、冒泡排序 • 冒泡排序:基本过程:重复地走访要排序的数列,一次比较相邻的两个元素,如果他们的顺序错误就把他们交换过来。不断重复这个过程,直到没有元素需要交换,排序就完成了。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。 具体可以描述为:将序列中第1个和第2个元素进行比较,如果前者大于后者,则交换两者的位置,否则位置不变;然后将第2个元素与第3个元素进行比较,如果前者大于后者,则交换两者的位置,否则位置不变;依此类推,直到最后两个元素比较完毕为止。这就是第一次冒泡排序,这个过程完成后,最大的元素就被安放在了最后一个位置上。下面对前面n-1个元素进行第二次冒泡排序,将这n-1个元素中的最大值安放在了n-1的位置上。下面再对前面的n-2个元素进行第三轮冒泡排序。如此进行下去,但执行完第n-1轮冒泡排序后,整个排序就完成了。
Matlab 程序 % 冒泡排序 Matlab 程序 function x = Sort_Bubble(x,n) for k = 1 : n flag = 0; % 用于记录是否有需要交换的元素 for i = 1 : n-k if x(i) > x(i+1) flag = 1; t = x(i); x(i) = x(i+1); x(i+1) = t; end end if flag==0 % 如果这次遍历没有元素需要交换,那么排序结束 break; end end
五、快速排序 • 快速排序:算法思想: 选定其中一个中间元素,将原序列分割成两部分,使得分割之后的序列的前面一个部分的元素都小于这个中间元素,而后面部分的元素都大于等于这个中间元素。依此类推,再对这两个分割好的子序列进行上述的过程,直到排序结束。
% 快速排序 Matlab 程序 function Sort_Quick(low,high) global xx if low < high n = partition(low,high); Sort_Quick(low,n);Sort_Quick(n+1,high); end function low = partition(low,high) global xx % 对一个给定范围的子序列选定一个中间元素, 即分割元素,执行完函数之后返回分割 % 元素所在的位置,在分割元素之前的元素都小于这个中间元素,在它后面的元素都 % 大于等于这个中间元素 pivot = xx(low); % 采用子序列的第一个元素为中间元素 while (low < high) while low<high && xx(high) >= pivot high=high-1; % 从后往前, 在后半部分中寻找第一个小于中间元素的元素 end t=xx(low); xx(low)=xx(high); xx(high)=t;% 将这个元素交换到前半部分 while low<high && xx(low) <= pivot low=low+1; % 从前往后在前半部分中寻找第一个大于中间元素的元素 end t=xx(low); xx(low)=xx(high); xx(high)=t; % 将这个元素交换到后半部分 end Matlab 程序
上机作业 • 编写插入排序的 C++ 程序,程序取名 hw08_01.cpp • 编写 Shell 排序的 C++ 程序,程序取名 hw08_02.cpp • (3) 编写冒泡排序的 C++ 程序,程序取名 hw08_03.cpp