c++代码实现各种排序算法

本文详细介绍了多种经典的排序算法,包括冒泡排序、插入排序、选择排序等,并提供了每种算法的具体实现代码,帮助读者深入理解各种排序算法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   /*************************气泡排序*****************************/




// 冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。
// 即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,
// 将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。
// 在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),
// 将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),
// 第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。
// 如此下去,重复以上过程,直至最终完成排序。

void bubbleSort(int* a, int num) {
   int temp;
   for(int i=1; i<num ;i++) {
         for(int j=0; j<num-i ; j++) {
if(a[j]>a[j+1]) {
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}

/*************************鸡尾酒排序*****************************/
// 鸡尾酒排序,也就是定向冒泡排序, 鸡尾酒搅拌排序, 搅拌排序 (也可以视作选择排序的一种变形),
// 涟漪排序, 来回排序 or 快乐小时排序, 是冒泡排序的一种变形。
// 此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序。

void cocktailSort(int *a, int num) {
int temp;
for(int i=0; i<ceil(num/2); i++) {
for(int j=i; j<num-i-1; j++) {
if(a[j]>a[j+1]) {
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
for(int k = j; k>i+1; k--) {
if(a[k]<a[k-1]) {
temp = a[k];
a[k] = a[k-1];
a[k-1] = temp;
}
}
}
}

/************************插入排序*****************************/
// 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,
// 但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,
// 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、
// 个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
// 插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外,
// 而第二部分就只包含这一个元素。在第一部分排序后,
// 再把这个最后元素插入到此刻已是有序的第一部分里的位置

void insertionSort(int *a, int num) {
int temp;
for(int i=1; i<num; i++) {
for(int j=i; j>0; j--) {
if(a[j]<a[j-1]) {
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
}

/************************选择排序*****************************/
// 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,
// 顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
// 选择排序是不稳定的排序方法。

void selectSort(int *a, int num) {
int temp;
int index;
for(int i=0; i<num; i++) {
temp = a[i];
index = i;
for(int j=i; j<num; j++) {
if(temp>a[j]) {
temp = a[j];
index = j;
}
}
temp = a[i];
a[i] = a[index];
a[index] = temp;
}
}

/************************快速排序*****************************/
// 快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。
// 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,
// 其中一部分的所有数据都比另外一部分的所有数据都要小,
// 然后再按此方法对这两部分数据分别进行快速排序,
// 整个排序过程可以递归进行,以此达到整个数据变成有序序列。

void quickSort(int *a, int low, int hight) {
if(low < hight) {
int l,h,temp;
l = low; h = hight;
temp = a[low];
while(l < h) {
while(l < h && temp <= a[h]) h--;
a[l] = a[h];
while(l < h && temp >= a[l]) l++;
a[h] = a[l];
}
a[l] = temp;
quickSort(a, low, l-1);
quickSort(a, h+1, hight);
}
}

/************************希尔(shell)排序*****************************/
// 希尔排序基本思想:
// 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
// 所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插入排序;
// 然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<;…<d2<d1),
// 即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。
// 算法步骤:
// Step1 将n个元素个数列分为5个小组,在每个小组内按直接插入法排序;
// step2 在第i步,分组个数取 di+1 =(di +1)/2 {9,5,3,2,1};相临两组之间的对应元素进行比较,
// 如果ai>aj,则交换它们的位置;
// Step3 当dK = 1的循环过程完成后,排序过程结束。
void shellInsert(int *a, int num, int dk) {
int temp;
for(int i=dk; i<num; i++) {
temp = a[i];
for(int j=i-dk; j>=0; j-=dk) {
if(a[j+dk] < a[j]) {
temp = a[j];
a[j] = a[j+dk];
a[j+dk] = temp;
}
}
}
}
void shellSort(int *a, int num,int *dlta,int dnum) {
for(int i=0; i<=dnum; i++) {
shellInsert(a, num, dlta[i]);
}
}


/************************堆排序*****************************/
//建立大顶堆,排序才为非递减
//http://blog.youkuaiyun.com/morewindows/article/details/6709644
//调整从i到n节点的堆
void heapAdjust(int *a, int i, int n) {
int temp = a[i];
for(int j=2*i+1; j<n; j=j*2+1) {
if(j+1<n && a[j] > a[j+1]) j++;
if(temp <= a[j]) break;
a[i] = a[j];
i = j;
}
a[i] = temp;
}
void heapSortm(int *a, int num) {
//建堆
for(int i=num/2-1; i>=0; i--) {
heapAdjust(a,i,num);
}
//排序
int temp;
for(i=num-1; i>0 ;i--) {
temp = a[0];
a[0] = a[i];
a[i] = temp;
heapAdjust(a,0,i);
}
}

/************************归并排序*****************************/
//http://blog.youkuaiyun.com/morewindows/article/details/6678165

//将数组的两个有序的元素合并a[first...mid],a[mid+1.....last]
//合并后的元素放在a[first.....last]中
void merge(int *a, int *temp, int first, int mid, int last) {
int i,j,k;
i = first;
j = mid+1;
k = first;
for(;i<=mid && j<=last;k++) {
if(a[i]>a[j]) {
temp[k] = a[j++];
}else {
temp[k] = a[i++];
}
}
while(i<=mid) {
temp[k++] = a[i++];
}
while(j<=last) {
temp[k++] = a[j++];
}
for(i=first; i<k; i++) {
a[i] = temp[i];
}
}

void MSort(int *a, int *temp, int first, int last) {
if(first<last) {
int mid = (first+last)/2;
MSort(a,temp,first,mid);
MSort(a,temp,mid+1,last);
merge(a,temp,first,mid,last);
}
}
void mergeSort(int *a, int num) {
int *temp = new int[num];
//int *temp = (int *)malloc(sizeof(int)*num);
MSort(a,temp,0,num-1);
delete temp;
//free(temp);
}

/************************二叉树排序(二叉排序树)**************************/
//二叉树
typedef struct BTree {
int number;
struct BTree *leftChild;
struct BTree *rightChild;
}BTree;

void insertOneNodeToBTree(BTree *btree, int number) {
if(btree != NULL) {
BTree *bNode = new BTree();
bNode->number = number;
bNode->leftChild = NULL;
bNode->rightChild = NULL;
BTree *temp;
temp = btree;
while(temp != NULL) {
if(temp->number < number) {
if(temp->rightChild == NULL) {
temp->rightChild = bNode;
return;
}
temp = temp->rightChild;
}else {
if(temp->leftChild == NULL) {
temp->leftChild = bNode;
return;
}
temp = temp->leftChild;
}
}
}else {
cout<<"不能往空树中插入数据!!!!"<<endl;
}
}

BTree *createBTree(int *arr, int number) {
BTree *btree = NULL;
btree = new BTree();
btree->number = arr[0];
btree->leftChild = NULL;
btree->rightChild = NULL;
for(int i=1; i<number; i++) {
insertOneNodeToBTree(btree,arr[i]);
}
return btree;
}
//中序递归遍历
void midSortBTree(BTree *btree,int *a,int &p) {
if(btree != NULL) {
midSortBTree(btree->leftChild,a,p);
a[p++] = btree->number;
midSortBTree(btree->rightChild,a,p);
}
}
//中序非递归遍历(有时间再写)


/************************桶排序**************************/
// 桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将阵列分到有限数量的桶子里。
// 每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序)。
// 桶排序是鸽巢排序的一种归纳结果。当要被排序的阵列内的数值是均匀分配的时候,
// 桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。
// 例如要对大小为[1..1000]范围内的n个整数A[1..n]排序,可以把桶设为大小为10的范围,
// 具体而言,设集合B[1]存储[1..10]的整数,集合B[2]存储(10..20]的整数,……集合B[i]
// 存储((i-1)*10, i*10]的整数,i = 1,2,..100。总共有100个桶。然后对A[1..n]从头到尾扫描一遍,
// 把每个A[i]放入对应的桶B[j]中。 然后再对这100个桶中每个桶里的数字排序,这时可用冒泡,选择,
// 乃至快排,一般来说任何排序法都可以。最后依次输出每个桶里面的数字,且每个桶中的数字从小到大输出,
// 这样就得到所有数字排好序的一个序列了。假设有n个数字,有m个桶,如果数字是平均分布的,
// 则每个桶里面平均有n/m个数字。如果对每个桶中的数字采用快速排序,
// 那么整个算法的复杂度是O(n+m*n/m*log(n/m))=O(n+nlogn-nlogm)

typedef struct barrel {
int node[10];
int count;/* the num of node */
}barrel;

void bucket_sort(int data[], int size) {
int max,min,num,pos;
barrel *pBarrel = NULL;

max = min = data[0];
for(int i=0; i<size; i++) {
if(data[i] > max) {
max = data[i];
}
if(data[i] < min) {
min = data[i];
}
}
num = (max-min+1)/10+1;
pBarrel = (barrel*)malloc(sizeof(barrel)*num);
//初始化为零
memset(pBarrel,0,sizeof(barrel)*num);

//将数据放在每个桶中
int k;
for(i=0; i<size; i++) {
k = (data[i]-min+1)/10;
(pBarrel+k)->node[(pBarrel+k)->count++] = data[i];
}

pos = 0;
for(i=0; i<num; i++) {
quickSort((pBarrel+i)->node, 0, (pBarrel+k)->count);
for(int j=0; j<(pBarrel+i)->count; j++) {
data[pos++] = (pBarrel+i)->node[i];
}
}
free(pBarrel);
}


/************************基数排序**************************/
//http://blog.youkuaiyun.com/feixiaoxing/article/details/6876831
//http://www.cnblogs.com/kkun/archive/2011/11/23/2260275.html



/************************图书馆排序**************************/
//http://qubernet.blog.163.com/blog/static/17794728420111199573199/\
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值