您的位置:首页 > 其它

笔记二:计数排序、选择排序、冒泡排序、插入排序

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: