8.3 内部排序法---交换类排序(冒泡、快排)
来源:互联网 发布:mac迅雷下载提示版权 编辑:程序博客网 时间:2024/04/30 04:48
交换类排序:主要是不断的比较两个元素的大小并交换其原始的位置,完成一趟排序之后,最大的元素(或最小的元素)被排在最后(或者最前)。重复以上操作若干趟后,元素序列成为一个有序序列。主要有冒泡排序和快速排序。时间复杂度分别为:O(n^2)和O(nlogn)。
冒泡排序思想:依次比较两个相邻的数,把较小的数放在前面,把较大的数放在后面。
快速排序的思想:快排不是比较两个相邻的元素,而是将指定的元素与序列中的元素依次比较,将逆序的两个元素交换。
下面是简单的冒泡排序和快排的简单操作:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/***********************************************************/
// 程序名称:SwapSort.cpp
// 程序目的:内部排序法---交换式排序
// 程序来源:数据结构与算法分析(C语言版) P-237
// 日期:2013-9-4 15:20:37 JohnnyHu修改
/***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#define Error( str ) FatalError( str )
#define FatalError( str ) fprintf( stderr, "%s\n", str ), exit( 1 )
#define MAX 5
typedef int ElementType;
void Swap(ElementType& lValue, ElementType& rValue)
{
ElementType tmp = lValue;
lValue = tmp;
lValue = rValue;
rValue = tmp;
}
void BubbleSort(ElementType a[], int n);
void InsertionSort(ElementType a[], int n);
void QuickSort1(ElementType a[], int n);
void PrintSort(ElementType a[], int n);
int main(void)
{
int data[MAX] = {89, 12, 45, 8, 33};
printf("排序前: ");
PrintSort(data, MAX);
//BubbleSort(data, MAX);
QuickSort1(data, MAX);
//QuickSort2(data, MAX);
printf("排序后: ");
PrintSort(data, MAX);
return 0;
}
/************************************************************************/
// 冒泡排序
/************************************************************************/
void BubbleSort(ElementType a[], int n)
{
bool bChanged; // 记录数值位置是否交换
bChanged = true;
for (int i = n-1; i > 1 && bChanged; i--)
{
bChanged = false;
for (int j=0; j < i; j++)
{
if (a[j] > a[j+1])
{
Swap(a[j], a[j+1]); // 较大的数据始终在后面
bChanged = true;
}
}
}
return;
}
/************************************************************************/
// 直接插入插入排序
/************************************************************************/
void InsertionSort(ElementType a[], int n)
{
ElementType tmp;
for (int i = 1; i < n; i++)
{
tmp = a[i]; // 取出第i个元素
int j = i;
for ( ; j > 0 && a[j-1] > tmp; j--)
{ // 从后往前寻找插入位置
a[j] = a[j - 1];
}
a[j] = tmp; // a[i]插入正确位置
}
}
// 快排的核心部分
void Qsort1(ElementType a[], int low, int high)
{
int left = low;
int right = high;
ElementType pivot = a[low]; // 轴枢元素
while (left < right)
{
while (left < right && pivot <= a[right])
right--; // 从后往前找小于pivot的元素
if (left < right)
{ // 将小于pivot的元素a[right]存入a[left]
a[left] = a[right];
left++;
}
while (left < right && pivot > a[left])
left++; // 从前往后找大于pivot的元素
if (left < right)
{
a[right] = a[left];
right--;
}
}
a[left] = pivot; // 轴枢元素存入a[left]
if (low < left)
Qsort1(a, low, left - 1);
if (left > high)
Qsort1(a, right+1, high);
return;
}
/************************************************************************/
// 快速排序1
/************************************************************************/
void QuickSort1(ElementType a[], int n)
{
int low, high;
low = 0;
high = n - 1;
Qsort1(a, low, high);
return;
}
/************************************************************************/
// 打印排序表
/************************************************************************/
void PrintSort(ElementType a[], int n)
{
for (int i = 0; i < n; i++)
printf("[%d]\t", a[i]);
printf("\n");
return;
}
// 程序名称:SwapSort.cpp
// 程序目的:内部排序法---交换式排序
// 程序来源:数据结构与算法分析(C语言版) P-237
// 日期:2013-9-4 15:20:37 JohnnyHu修改
/***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#define Error( str ) FatalError( str )
#define FatalError( str ) fprintf( stderr, "%s\n", str ), exit( 1 )
#define MAX 5
typedef int ElementType;
void Swap(ElementType& lValue, ElementType& rValue)
{
ElementType tmp = lValue;
lValue = tmp;
lValue = rValue;
rValue = tmp;
}
void BubbleSort(ElementType a[], int n);
void InsertionSort(ElementType a[], int n);
void QuickSort1(ElementType a[], int n);
void PrintSort(ElementType a[], int n);
int main(void)
{
int data[MAX] = {89, 12, 45, 8, 33};
printf("排序前: ");
PrintSort(data, MAX);
//BubbleSort(data, MAX);
QuickSort1(data, MAX);
//QuickSort2(data, MAX);
printf("排序后: ");
PrintSort(data, MAX);
return 0;
}
/************************************************************************/
// 冒泡排序
/************************************************************************/
void BubbleSort(ElementType a[], int n)
{
bool bChanged; // 记录数值位置是否交换
bChanged = true;
for (int i = n-1; i > 1 && bChanged; i--)
{
bChanged = false;
for (int j=0; j < i; j++)
{
if (a[j] > a[j+1])
{
Swap(a[j], a[j+1]); // 较大的数据始终在后面
bChanged = true;
}
}
}
return;
}
/************************************************************************/
// 直接插入插入排序
/************************************************************************/
void InsertionSort(ElementType a[], int n)
{
ElementType tmp;
for (int i = 1; i < n; i++)
{
tmp = a[i]; // 取出第i个元素
int j = i;
for ( ; j > 0 && a[j-1] > tmp; j--)
{ // 从后往前寻找插入位置
a[j] = a[j - 1];
}
a[j] = tmp; // a[i]插入正确位置
}
}
// 快排的核心部分
void Qsort1(ElementType a[], int low, int high)
{
int left = low;
int right = high;
ElementType pivot = a[low]; // 轴枢元素
while (left < right)
{
while (left < right && pivot <= a[right])
right--; // 从后往前找小于pivot的元素
if (left < right)
{ // 将小于pivot的元素a[right]存入a[left]
a[left] = a[right];
left++;
}
while (left < right && pivot > a[left])
left++; // 从前往后找大于pivot的元素
if (left < right)
{
a[right] = a[left];
right--;
}
}
a[left] = pivot; // 轴枢元素存入a[left]
if (low < left)
Qsort1(a, low, left - 1);
if (left > high)
Qsort1(a, right+1, high);
return;
}
/************************************************************************/
// 快速排序1
/************************************************************************/
void QuickSort1(ElementType a[], int n)
{
int low, high;
low = 0;
high = n - 1;
Qsort1(a, low, high);
return;
}
/************************************************************************/
// 打印排序表
/************************************************************************/
void PrintSort(ElementType a[], int n)
{
for (int i = 0; i < n; i++)
printf("[%d]\t", a[i]);
printf("\n");
return;
}
当然冒泡排序也可以这样写:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/************************************************************************/
// 冒泡排序
/************************************************************************/
void BubbleSort(ElementType a[], int n)
{
//bool bChanged; // 记录数值位置是否交换
//bChanged = true;
//for (int i = n-1; i > 1 && bChanged; i--)
//{
// bChanged = false;
// for (int j=0; j < i; j++)
// {
// if (a[j] > a[j+1])
// {
// Swap(a[j], a[j+1]); // 较大的数据始终在后面
// bChanged = true;
// }
// }
//}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i - 1; i++)
{
if (a[j] > a[j=1])
Swap(a[j], a[j+1]);
}
}
return;
}
// 冒泡排序
/************************************************************************/
void BubbleSort(ElementType a[], int n)
{
//bool bChanged; // 记录数值位置是否交换
//bChanged = true;
//for (int i = n-1; i > 1 && bChanged; i--)
//{
// bChanged = false;
// for (int j=0; j < i; j++)
// {
// if (a[j] > a[j+1])
// {
// Swap(a[j], a[j+1]); // 较大的数据始终在后面
// bChanged = true;
// }
// }
//}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i - 1; i++)
{
if (a[j] > a[j=1])
Swap(a[j], a[j+1]);
}
}
return;
}
上面的快排1是每次排序时均将第一个元素作为轴枢元素,是最为简洁的一种,其实,轴枢元素的选择有多种方法,轴枢元素的选择对快排算法的效率有着重大的影响,所以上面的快排1有一定的缺陷,下面介绍快排2,改变主意针对的是轴枢元素的选择采用三数值分割策略:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/************************************************************************/
// 直接插入插入排序
/************************************************************************/
void InsertionSort(ElementType a[], int n)
{
ElementType tmp;
for (int i = 1; i < n; i++)
{
tmp = a[i]; // 取出第i个元素
int j = i;
for ( ; j > 0 && a[j-1] > tmp; j--)
{ // 从后往前寻找插入位置
a[j] = a[j - 1];
}
a[j] = tmp; // a[i]插入正确位置
}
}
// 3数中值分割法
ElementType Median3(ElementType a[], int letf, int right)
{
int center = (letf + right) / 2;
if (a[letf] > a[center])
Swap(a[letf], a[center]);
if (a[letf] > a[right])
Swap(a[letf], a[right]);
if (a[center] > a[right])
Swap(a[center], a[right]);
// 此时a[left] <= a[center] <= a[right]
Swap(a[center], a[right - 1]); // 将枢纽元放到数组right-1的位置
return a[right - 1]; // 放回枢纽元
}
// 快排核心部分
#define CUTOFF 3
void Qsort2(ElementType a[], int left, int right)
{
ElementType pivot; // 枢纽元
if (left + CUTOFF <= right)
{ // 保证数组中有3个以上的元素
pivot = Median3(a, left, right);
int i = left;
int j = right - 1;
for ( ; ; )
{
while (a[++i] < pivot) { }
while (a[--j] > pivot) { }
if (i < j)
Swap(a[i], a[j]);
else
break;
}
Swap(a[i], a[right - 1]); // 将pivot在存储在right-1中
Qsort2(a, left, i - 1);
Qsort2(a, i + 1, right);
}
else // 在子数组上j进行插入排序
InsertionSort(a + left, right - left + 1);
return;
}
/************************************************************************/
// 快速排序2
/************************************************************************/
void QuickSort2(ElementType a[], int n)
{
Qsort2(a, 0, n - 1);
}
// 直接插入插入排序
/************************************************************************/
void InsertionSort(ElementType a[], int n)
{
ElementType tmp;
for (int i = 1; i < n; i++)
{
tmp = a[i]; // 取出第i个元素
int j = i;
for ( ; j > 0 && a[j-1] > tmp; j--)
{ // 从后往前寻找插入位置
a[j] = a[j - 1];
}
a[j] = tmp; // a[i]插入正确位置
}
}
// 3数中值分割法
ElementType Median3(ElementType a[], int letf, int right)
{
int center = (letf + right) / 2;
if (a[letf] > a[center])
Swap(a[letf], a[center]);
if (a[letf] > a[right])
Swap(a[letf], a[right]);
if (a[center] > a[right])
Swap(a[center], a[right]);
// 此时a[left] <= a[center] <= a[right]
Swap(a[center], a[right - 1]); // 将枢纽元放到数组right-1的位置
return a[right - 1]; // 放回枢纽元
}
// 快排核心部分
#define CUTOFF 3
void Qsort2(ElementType a[], int left, int right)
{
ElementType pivot; // 枢纽元
if (left + CUTOFF <= right)
{ // 保证数组中有3个以上的元素
pivot = Median3(a, left, right);
int i = left;
int j = right - 1;
for ( ; ; )
{
while (a[++i] < pivot) { }
while (a[--j] > pivot) { }
if (i < j)
Swap(a[i], a[j]);
else
break;
}
Swap(a[i], a[right - 1]); // 将pivot在存储在right-1中
Qsort2(a, left, i - 1);
Qsort2(a, i + 1, right);
}
else // 在子数组上j进行插入排序
InsertionSort(a + left, right - left + 1);
return;
}
/************************************************************************/
// 快速排序2
/************************************************************************/
void QuickSort2(ElementType a[], int n)
{
Qsort2(a, 0, n - 1);
}
- 8.3 内部排序法---交换类排序(冒泡、快排)
- 交换类排序:冒泡排序(优化)和快排
- 交换排序总结(快排,冒泡)
- 交换排序:快排VS冒泡
- 交换排序------快排
- 排序算法之交换排序(冒泡和快排)
- 冒泡排序,快排
- 冒泡排序,快排
- 交换排序之冒泡与快排C/C++
- 冒泡排序和快排的交换次数
- 内部交换排序---冒泡排序
- 内部排序-交换式排序-冒泡排序法
- 5类内部排序----交换排序之冒泡排序
- 采用回调函数的内部排序算法-插入排序,希尔排序,冒泡,快排,堆排,归并排,基数排序
- 采用回调函数的内部排序算法-插入排序,希尔排序,冒泡,快排,堆排,归并排,基数排序
- 数据结构与算法专题之查找与排序——交换类排序(冒泡、快排与归并)
- sdut oj3399 数据结构实验之排序二:交换排序(快排+冒泡)
- 暑假集训 8.13 数据结构实验之排序二:交换排序 (冒泡 与 快排.....)
- UVA - 11464 Even Parity
- SQLServer事务的隔离级别
- Deep Learning_mnist background introduction
- 为什么 Objective-C 很难
- (function($){...})(jQuery)的意思
- 8.3 内部排序法---交换类排序(冒泡、快排)
- HighGUI视频读写函数解析
- Asterisk 12 Alpha版本发布
- Android:将电脑上的文件传输到模拟器的sdcard上
- Python 将excel部分内容导入到XML文件
- 应用程序签名机制进一步说明
- Android ViewFlipper的使用
- PL/SQL连64位Oracle11g R2 win7 64旗舰环境
- S3C2410 实验七—— 实时时钟(RTC)实验(未完)