数据结构学习笔记 --- 排序(冒泡排序、快速排序)
2017-02-22 07:10
495 查看
1. 引言
本文主要讲解一些常见的排序算法。
2. 冒泡排序
冒泡排序是经过n-1趟子排序完成的,第i趟子排序从第1个数至第n-i个数,若第i个数比后一个数大(则升序,小则降序)则交换两数。
3. 快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。由C.
A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1即J--),找到第一个小于key的值A[j],A[j]与A[i]交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1即I++),找到第一个大于key的A[i],A[i]与A[j]交换;
5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)
本文主要讲解一些常见的排序算法。
2. 冒泡排序
冒泡排序是经过n-1趟子排序完成的,第i趟子排序从第1个数至第n-i个数,若第i个数比后一个数大(则升序,小则降序)则交换两数。
#include "ds.h" #define N 8 // 将a中整数序列重新排列成自小至大有序的整数序列(起泡排序) void bubble_sort(int a[],int n) { int i, j, t; Status change; for (i = n - 1, change = TRUE; i > 0 && change; --i) { change = FALSE; for (j = 0; j < i; j++) { if (a[j] > a[j+1]) { t = a[j]; a[j] = a[j+1]; a[j+1] = t; change = TRUE; } } } } void print(int r[],int n) { int i; for(i = 0; i < n; i++) printf("%d ", r[i]); printf("\n"); } int main() { int d ={49,38,65,97,76,13,27,49}; printf("排序前:\n"); print(d,N); bubble_sort(d,N); printf("排序后:\n"); print(d,N); }
3. 快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。由C.
A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1即J--),找到第一个小于key的值A[j],A[j]与A[i]交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1即I++),找到第一个大于key的A[i],A[i]与A[j]交换;
5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)
#include "ds.h" #define MAX_SIZE 20 // 一个用作示例的小顺序表的最大长度 typedef int KeyType; // 定义关键字类型为整型 typedef int InfoType; // 定义其它数据项的类型 #define EQ(a,b) ((a)==(b)) #define LT(a,b) ((a)<(b)) #define LQ(a,b) ((a)<=(b)) struct RedType // 记录类型 { KeyType key; // 关键字项 InfoType otherinfo; // 其它数据项,具体类型在主程中定义 }; struct SqList // 顺序表类型 { RedType r[MAX_SIZE+1]; // r[0]闲置或用作哨兵单元 int length; // 顺序表长度 }; // 交换顺序表L中子表L.r[low..high]的记录,使枢轴记录到位, // 并返回其所在位置,此时在它之前(后)的记录均不大(小)于它。算法10.6(a) int Partition(SqList &L,int low,int high) { #if 1 KeyType pivotkey; L.r[0] = L.r[low]; // 用子表的第一个记录作枢轴记录 pivotkey = L.r[low].key; // 枢轴记录关键字 while(low < high) { // 从表的两端交替地向中间扫描 while(low<high&&L.r[high].key>=pivotkey) --high; L.r[low]=L.r[high]; // 将比枢轴记录小的记录移到低端 while(low<high&&L.r[low].key<=pivotkey) ++low; L.r[high]=L.r[low]; // 将比枢轴记录大的记录移到高端 } L.r[low] = L.r[0]; // 枢轴记录到位 return low; // 返回枢轴位置 #else RedType t; KeyType pivotkey; pivotkey = L.r[low].key; // 用子表的第一个记录作枢轴记录 while (low < high) { // 从表的两端交替地向中间扫描 while (low < high && L.r[high].key >= pivotkey) --high; // 将比枢轴记录小的记录交换到低端 t = L.r[low]; L.r[low] = L.r[high]; L.r[high] = t; while (low < high && L.r[low].key <= pivotkey) ++low; // 将比枢轴记录大的记录交换到高端 t = L.r[low]; L.r[low] = L.r[high]; L.r[high] = t; } return low; // 返回枢轴所在位置 #endif } // 快速排序的函数,包括算法10.7、10.8 void QSort(SqList &L, int low, int high) { // 对顺序表L中的子序列L.r[low..high]作快速排序。算法10.7 int pivotloc; if (low < high) // 长度大于1 { pivotloc = Partition(L, low, high); // 将L.r[low..high]一分为二 QSort(L, low, pivotloc - 1); // 对低子表递归排序,pivotloc是枢轴位置 QSort(L, pivotloc + 1, high); // 对高子表递归排序 } } // 对顺序表L作快速排序。 void QuickSort(SqList &L) { QSort(L, 1, L.length); } void print(SqList L) { int i; for(i = 1; i <= L.length; i++) printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo); printf("\n"); } #define N 8 int main() { RedType d ={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}}; SqList l; int i; for(i=0;i<N;i++) l.r[i+1]=d[i]; l.length=N; printf("排序前:\n"); print(l); QuickSort(l); printf("排序后:\n"); print(l); }
相关文章推荐
- 数据结构学习笔记 --- 排序(冒泡排序、快速排序)
- 数据结构学习笔记23 快速排序和基尔排序
- 学习笔记:冒泡排序、插入排序、选择排序、快速排序的实现
- 数据结构学习笔记一:简单排序与查询算法
- 黑马程序员—Java基础学习笔记之排序算法:选择排序&冒泡排序
- 数据结构学习笔记-排序2
- 数据结构学习笔记 --- 排序(Gnome排序、梳排序)
- python数据结构学习笔记-2016-10-23-02-排序
- 数据结构学习笔记----排序
- 冒泡排序 直接排序 学习笔记
- 【数据结构学习笔记】——排序
- 图解"数据结构--内部排序算法"----交换排序:冒泡排序、快速排序
- 数据结构学习笔记 --- 排序(选择排序、堆排序)
- [学习笔记]排序算法之冒泡排序
- 【python 数据结构 1:排序】冒泡排序和快速排序
- 【郝斌数据结构自学笔记】75-78_链式二叉树遍历具体程序演示_5种常用排序概述和快速排序详细讲解_再次讨论什么是数据结构_再次讨论到底什么是泛型
- 黑马程序员之数据结构学习笔记:快速排序
- 数据结构学习笔记 --- 排序(归并排序、基数排序)
- 数据结构复习笔记:使用PHP实现内排序之冒泡排序和简单选择排序
- 数据结构学习笔记3.2—快速排序