笔记二:计数排序、选择排序、冒泡排序、插入排序
2016-04-26 15:04
681 查看
计数排序
1、 名次 :所谓名次,通俗理解即为该元素在序列中排行老几的意思。2.、如何求名次:依次对每一个元素进行比较,若排在自己(该元素)前面的元素比自己大,则前面的元素在排行计数上加1,反之则自己加1。
3、利用附加数组的计数排序:根据自身名次重新整理一份排序序列存储在附加数组中,然后将附加数组值拷贝到原序列中。
1)代码:
template<typename T> void SortClass<T>::rank(T a[], int n, int r[]) { //给数组a[0: n-1]的n个元素排名次 //结果在r[0: n-1]中返回 for (int i = 0; i < n; i++) r[i] = 0; //比较所有元素,每次比较中较大元素计数器加1 for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) if (a[j] <= a[i]) { ++r[i]; } else { ++r[j]; } }//rank template<typename T> void SortClass<T>::rearrange(T a[], int n) { T *u = new T ; //临时数组,存储排序元素 int *r = new int ; //存储数组元素名次 rank(a, n, r); for (int i = 0; i < n; i++) u[r[i]] = a[i]; for (int i = 0; i < n; i++) a[i] = u[i]; delete [] u; delete[] r; }//rearrange
2)运行:
3)时间复杂度分析:在求名次rank()操作中,针对第i个元素,比较的次数为i次,因此总的比较次数为:1+2+3+…+(n-1)=(n-1)n/2次。在rearrange()中有2次for循环进行赋值操作,总的移动次数是2n。两者相加,得出附加数组的计数排序时间复杂度为:(n-1)n/2+2n =O(n2)(注:2为n的上标)
4、原地排序:所谓原地排序就是指在对序列元素进行名次计算之后,根据名次调整原序列的顺序,不借助附加数组。
1)思路:假设第一个元素a[0]的名次r[0]=3,那么,a[0]的值应该交换到下标为3的位置,即a[0]与a[3]交换。由于元素位置交换了,那么相应的,元素对应名次也要交换。停止交换的前提是a[0]元素对应的r[0]正好为0,则此时a[0]才是正确的元素。对其他位置元素,同理。
2 ) 代码:
template<typename T> void SortClass<T>::selfrearrange(T a[], int n) { int *r = new int ; //存储数组元素名次 rank(a, n, r); for (int i = 0; i < n; i++) while (i != r[i]) //当i == r[i]时,表明名次对应的下标存储元素正确 { int tmp = r[i]; swap(a[i], a[tmp]); //元素交换 swap(r[i], r[tmp]); //排名交换 } delete[] r; }//selfrearrange
3)运行:
4)时间复杂度分析:名次比较次数:1+2+3+…+(n-1)=(n-1)n/2次。交换次数:当序列有序时,交换0次,当序列无序时,由于每次交换,至少使一个元素交换到正确位置,那么对任意一个元素而言,最多的交换次序是(n-1)次,在这(n-1)次交换中,其他元素也被交换正确,故最多的交换次数为(n-1)次。原地重排最坏的时间复杂度为:(n-1)n/2+(n-1)=O(n2)。
选择排序
1、定义:第一次遍历序列,找出最大元素,将该元素排到末尾去;第二次遍历序列,找出次最大元素,将该元素排到末尾前一位置去;同理,继续下去,直到最后一个元素为止。2、思路:
3、基础选择排序:按照2中思路进行设计
1)代码:
template<typename T> void SortClass<T>::selectionSort(T a[], int n) { for (int i = n - 1; i > 0; i--) //移动的目标位置 { int indexOfMax = 0; for (int j = 0; j < i; j++) //找最大元素 if (a[indexOfMax] < a[j]) indexOfMax = j; swap(a[i], a[indexOfMax]); //将最大值移到目标位置 } }//selectionSort
2)运行:
3)时间复杂度分析:在进行查找最大元素值过程中,比较次数为(n-1)n/2。一次swap()操作,实际包含3步
tmp=a;a=b;b=a;,故移动次数为3(n-1)。基础选择排序的时间复杂度为(n-1)n/2+3(n-1)=O(n2)。
4、及时终止选择排序:在查找最大元素时,同时检查数组是否有序,减少不必要的迭代。
1)代码:
template<typename T> void SortClass<T>::selectionSortByOrder(T a[], int n) { bool sorted = false; for (int i = n - 1; i > 0 && !sorted; i--) //未排好序的情况下进行选择排序 { int indexOfMax = 0; sorted = true; for (int j = 0; j < i; j++) if (a[indexOfMax] < a[j]) { indexOfMax = j; } else { sorted = false; } swap(a[i], a[indexOfMax]); } }//selectionSortByOrder
2)运行:
冒泡排序
1、定义:简单来讲,相邻元素之间的比较,若前者较大,则交换。一轮比较即为一次冒泡过程。2、基础冒泡排序:
1)代码:
template<typename T> void SortClass<T>::bubbleSort(T a[], int n) { for (int i = 0; i < n; i++) for (int j = 0; j < n - 1; j++) if (a[j] > a[j + 1]) swap(a[j], a[j + 1]); }//bubbleSort
2)运行:
3、及时终止的冒泡排序:
1)代码:
template<typename T> void SortClass<T>::bubbleSortByOrder(T a[], int n) { bool sorted = true; for (int i = 0; i < n; i++) { for (int j = 0; j < n - 1; j++) if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); sorted = false; //只要交换顺序,表明排序未结束 } if (sorted) break; } }//bubbleSortByOrder
2)运行:
插入排序
1、定义: 把序列第一个元素看做一个有序数组,将第2个元素按顺序插入到这个数组中,则这两个数组组成一个新的有序数组。将第3个元素插入到上述有序数组中,那么这3个有序数组又组成新的有序数组。如此,依次将后续元素插入到前面已排好的序列中,直至最后一个元素为止。2、将要插入元素与已知排序数组进行比较,从后往前逐一比较,若该元素较小,则将有序数组中元素后移一位,直到腾出可以插入的空位即可。
3、插入排序:
1)代码:
template<typename T> void SortClass<T>::insertSort(T a[], int n) { for (int i = 1; i < n; i++) { int j; int tmp = a[i]; for (j = i - 1; j >= 0 && a[j] > tmp; j--) //将大于a[i]的元素依次后移 { a[j + 1] = a[j]; } a[j + 1] = tmp; //将a[i]元素按顺序插入到a[0:i-1]中 } }//insertSort
2)运行:
附全代码:
#include<iostream>
using namespace std;
template <typename T> class SortClass
{
public:
void rank(T a[], int n, int r[]); //名次计算
void rearrange(T a[], int n); //利用附加数组计数排序
void selfrearrange(T a[], int n); //原地排序
void selectionSort(T a[], int n); //选择排序
void selectionSortByOrder(T a[], int n); //及时终止的选择排序
void bubbleSort(T a[], int n); //冒泡排序
void bubbleSortByOrder(T a[], int n); //及时终止的冒泡排序
void insertSort(T a[], int n); //插入排序
};
template<typename T> void SortClass<T>::rank(T a[], int n, int r[]) { //给数组a[0: n-1]的n个元素排名次 //结果在r[0: n-1]中返回 for (int i = 0; i < n; i++) r[i] = 0; //比较所有元素,每次比较中较大元素计数器加1 for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) if (a[j] <= a[i]) { ++r[i]; } else { ++r[j]; } }//rank template<typename T> void SortClass<T>::rearrange(T a[], int n) { T *u = new T ; //临时数组,存储排序元素 int *r = new int ; //存储数组元素名次 rank(a, n, r); for (int i = 0; i < n; i++) u[r[i]] = a[i]; for (int i = 0; i < n; i++) a[i] = u[i]; delete [] u; delete[] r; }//rearrange
template<typename T> void SortClass<T>::selfrearrange(T a[], int n) { int *r = new int ; //存储数组元素名次 rank(a, n, r); for (int i = 0; i < n; i++) while (i != r[i]) //当i == r[i]时,表明名次对应的下标存储元素正确 { int tmp = r[i]; swap(a[i], a[tmp]); //元素交换 swap(r[i], r[tmp]); //排名交换 } delete[] r; }//selfrearrange
template<typename T> void SortClass<T>::selectionSort(T a[], int n) { for (int i = n - 1; i > 0; i--) //移动的目标位置 { int indexOfMax = 0; for (int j = 0; j < i; j++) //找最大元素 if (a[indexOfMax] < a[j]) indexOfMax = j; swap(a[i], a[indexOfMax]); //将最大值移到目标位置 } }//selectionSort
template<typename T> void SortClass<T>::selectionSortByOrder(T a[], int n) { bool sorted = false; for (int i = n - 1; i > 0 && !sorted; i--) //未排好序的情况下进行选择排序 { int indexOfMax = 0; sorted = true; for (int j = 0; j < i; j++) if (a[indexOfMax] < a[j]) { indexOfMax = j; } else { sorted = false; } swap(a[i], a[indexOfMax]); } }//selectionSortByOrder
template<typename T> void SortClass<T>::bubbleSort(T a[], int n) { for (int i = 0; i < n; i++) for (int j = 0; j < n - 1; j++) if (a[j] > a[j + 1]) swap(a[j], a[j + 1]); }//bubbleSort
template<typename T> void SortClass<T>::bubbleSortByOrder(T a[], int n) { bool sorted = true; for (int i = 0; i < n; i++) { for (int j = 0; j < n - 1; j++) if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); sorted = false; //只要交换顺序,表明排序未结束 } if (sorted) break; } }//bubbleSortByOrder
template<typename T> void SortClass<T>::insertSort(T a[], int n) { for (int i = 1; i < n; i++) { int j; int tmp = a[i]; for (j = i - 1; j >= 0 && a[j] > tmp; j--) //将大于a[i]的元素依次后移 { a[j + 1] = a[j]; } a[j + 1] = tmp; //将a[i]元素按顺序插入到a[0:i-1]中 } }//insertSort
int main(int argc, char *argv[])
{
int a[6] = { 6, 5, 8, 4, 3, 1 };
cout << "原始数组顺序: ";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;
SortClass<int> SClass;
/*SClass.rearrange(a, 6);
cout << "采用附加数组计数排序:";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;*/
/*SClass.selfrearrange(a, 6);
cout << "采用重排计数排序: ";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;*/
/*SClass.selectionSort(a, 6);
cout << "采用选择排序: ";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;*/
/*SClass.selectionSortByOrder(a, 6);
cout << "采用及时终止选择排序:";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;*/
/*SClass.bubbleSort(a, 6);
cout << "采用冒泡排序: ";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;*/
/*SClass.bubbleSortByOrder(a, 6);
cout << "采用及时终止冒泡排序:";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;*/
SClass.insertSort(a, 6);
cout << "采用插入排序: ";
for (int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
相关文章推荐
- 第5周 经典小游戏程序 打飞机
- inf文件的编写
- UVA_11292_Dragon of Loowater
- SQL Server 2008怎么自动备份数据库
- 【并发编程】活跃性问题
- Marvell网卡win10下无法联网的解决方法
- android 自定义view
- In-App Purchase iap 内付费 二次验证代码 (java 服务器端)
- 2016年4月20
- DAY6:leetcode #13 Roman to Integer
- 第89讲:Spark Streaming on Kafka解析和安装实战
- JavaScript代码性能优化总结
- run and start
- web后门top
- mac下配置gdb调试golang
- 《精通CSS:高级Web标准解决方案》学习过程--V
- 解决监听状态显示 The listener supports no services
- 2016/4/26
- android屏幕适配全攻略
- Android 屏幕适配