第八讲:排序算法

Download Report

Transcript 第八讲:排序算法

第八讲 排序算法
1
主要内容
 最小排序
 插入排序
 希尔(Shell)排序
 冒泡排序
 快速排序
2
一、最小排序
 最小排序:找出最小值,将其与第一个位置的元素交
换,然后对剩余的序列重复以上过程,直至排序结束。
原始数列: 2
第1次排序:2
第2次排序:2
第3次排序:2
第4次排序:2
第5次排序:2
第6次排序:2
第7次排序:2
第8次排序:2
第9次排序:2
8
8
3
3
3
3
3
3
3
3
3
3
8
5
5
5
5
5
5
5
12
12
12
12
5
5
5
5
5
5
5
5
5
8
8
7
7
7
7
7
20
20
20
20
20
20
8
8
8
8
7
7
7
7
7
8
20
12
12
12
14
14
14
14
14
14
14
14
14
14
5
5
5
5
12
12
12
20
20
16
16
16
16
16
16
16
16
16
16
20
3
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
4
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; % 交换
}
}
5
二、插入排序
 插入排序:假设前面 k 个元素已经按顺序排好了,在排第 k+1 个
数时,将其插入到前面已排好的 k 个数中,使得插入后得到的 k+1 个数组
成的序列仍按值有序。如此下去直到遍历完序列的所有元素为止。
原始数列: 2
第1次排序:2
第2次排序:2
第3次排序:2
第4次排序:2
第5次排序:2
第6次排序:2
第7次排序:2
第8次排序:2
第9次排序:2
8
8
3
3
3
3
3
3
3
3
3
3
8
8
5
5
5
5
5
5
12
12
12
12
8
8
7
7
5
5
5
5
5
5
12
12
8
8
7
7
20
20
20
20
20
20
12
12
8
8
7
7
7
7
7
7
20
14
12
12
14
14
14
14
14
14
14
20
14
14
5
5
5
5
5
5
5
5
20
16
16
16
16
16
16
16
16
16
16
20
6
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
7
三、希尔(Shell)排序
 Shell 排序:又称为“缩小增量排序”(Diminishing
Increment Sort),由 Donald Shell 在1959年提出,是对插
入排序的一个改进。它每次排序时把序列按照某个增量分成
几个子序列,对这几个子序列进行插入排序,然后不断的缩
小增量扩大每个子序列的元素数量,直到增量为 1 的时候,
子序列就和原先的待排列序列一样了,而此时序列基本上已
经排序好了,因此只需要做少量的比较和移动就可以完成对
序列的排序。
8
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
9
四、冒泡排序
 冒泡排序:基本过程:重复地走访要排序的数列,一次
比较相邻的两个元素,如果他们的顺序错误就把他们交换过
来。不断重复这个过程,直到没有元素需要交换,排序就完
成了。这个算法的名字由来是因为越大的元素会经由交换慢
慢“浮”到数列的顶端。
具体可以描述为:将序列中第1个和第2个元素进行比较,如果前者大于
后者,则交换两者的位置,否则位置不变;然后将第2个元素与第3个元
素进行比较,如果前者大于后者,则交换两者的位置,否则位置不变;
依此类推,直到最后两个元素比较完毕为止。这就是第一次冒泡排序,
这个过程完成后,最大的元素就被安放在了最后一个位置上。下面对前
面n-1个元素进行第二次冒泡排序,将这n-1个元素中的最大值安放在了
n-1的位置上。下面再对前面的n-2个元素进行第三轮冒泡排序。如此进
行下去,但执行完第n-1轮冒泡排序后,整个排序就完成了。
10
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
11
五、快速排序
 快速排序:算法思想: 选定其中一个中间元素,将原
序列分割成两部分,使得分割之后的序列的前面一个部分的
元素都小于这个中间元素,而后面部分的元素都大于等于这
个中间元素。依此类推,再对这两个分割好的子序列进行上
述的过程,直到排序结束。
12
Matlab 程序
% 快速排序 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
13
上机作业
(1) 编写插入排序的 C++ 程序,
程序取名 hw08_01.cpp
排序函数名:void sort_insert(int * px, int n)
(2) 编写 Shell 排序的 C++ 程序,
程序取名 hw08_02.cpp
排序函数名: sort_shell(int * px, int n)
(3) 编写冒泡排序的 C++ 程序,
程序取名 hw08_03.cpp
排序函数名: sort_bubble(int * px, int n)
14