八大排序 C++
来源:互联网 发布:js代码混淆 编辑:程序博客网 时间:2024/06/11 04:56
01直接插入排序
void sort(int *a,int num)
{
int i ,j ,key ;
for ( i = 1; i < num; i++)
{
int key = a[i]; //哨兵,数组取值都是挖空
for ( j = i;j>0 && a[j-1] > key; j--)
{//挖空的前一个位置和key关键字比较
a[j] = a[j-1]; //往后移动元素
}
a[j] = key;
}//如果关键字大于前面的那个就直接插入
}
02简单选择排序
void sort(int *a, int n)
{
for (int i = 0; i < n; i++)
{
int key = a[i];
int index = i;
for (int j = i+1; j < n; j++)
{
if (a[j] < key)
{
key = a[j];
index = j;
}
}//寻找最小元素以及最小元素的下标
int tmp = a[i];//和之前的进行换序操作
a[index] = tmp;
a[i] = key;
}
}
03冒泡排序
void sort(int *a, int n)
{
for (int i = 0; i < n; i++) //外层循环控制排序次数
{
for (int j = 0; j < n - 1 - i; j++) //内层循环每排序一次就少一个数
{ //如果前面的比后面的大就后移动一个
if (a[j]>a[j + 1])
{
int tmp = a[j + 1];
a[j + 1] = a[j];
a[j] = tmp; //相邻两个进行比较,然后向后移动
}
}
}
}
04快速排序
void quick_sort(int a[], int l, int r)
{
if (l < r) //递归结束条件
{
int i = l; int j = r;
int x = a[l];
while (i<j)
{
while (i < j&&a[j] >= x)
j--;//从后往前面找比x小的,找到以后将其挖出来,然后前移
if (i < j)
a[i++] = a[j]; //把后面小的往前面扔
//这里的先进行a[i]=a[j]操作然后j+1
while (i < j&&a[i] < x)
i++;//从前往后面找比x大的,找到以后将其挖出来,然后后移
if (i < j)
a[j--] = a[i]; //把前面大的往后面扔
} //这里的先进行a[j]=a[i]操作然后j-1
a[i] = x; //这里填写a[i]或者a[j]都可以,每循环一次有一个坑,然后将关键码填入次坑
quick_sort(a, l, i - 1);
quick_sort(a, i + 1, r);
}
}
排序思想:(挖坑的时候指针不移动,填坑的时候,指针移动和查找顺序相反)
先规定一个枢纽,然后从右边往左边找第一个小于枢纽的然后将其取出,挖个坑,然后从左边往右边找第一个大于枢纽的,填入此坑,然后指针移动。
05希尔排序
void shellsort(int *a, int n)
{
int dk = n / 2;
while (dk >= 1)
{
shell_insert(a, n, dk);
dk = dk / 2;
}
void shell_insert(int *a, int n, int dk)
{
int i, j;
for (i = dk; i < n; i++)
{
int key = a[i];
for (j = i; j>0 && a[j - dk] > key; j = j - dk)
{
a[j] = a[j - dk];
}
a[j] = key;
}
}
排序思想:
分组有序,然后全部有序,
建议掌握第三种:
此种排序是插入排序的升级版
06堆排序
void creat_heap(int *a, int n)
{
for (int i = n / 2-1; i >= 0; i--) //传递来的起始节点之前的全部遍历
{
int max = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
if (l < n&&a[l]>a[max])
{
max = l;
}
if (r<n&&a[r]>a[max])
{
max = r;
}
if (max != i) {
swap(a[max], a[i]);//执行到此处完成对三个数字的比较
}
}
}
void heap_sort(int *a, int n)
{
creat_heap(a, n);//先创建一个顶堆,然后就可以进行换序
for (int i = n - 1; i > 0; i--) //在此处要遍历(n-1)次
{ //在此处交换位置,执行的是上次创建堆的结果
swap(a[0], a[i]);
creat_heap(a, i);
Print(a, n);
}
}
07归并排序
void MergeArray(int a[], int l, int mid, int r)
{
int m = mid;
int n = r;
int i = l;
int j = mid + 1;
int k = 0;
int tmp[N] = { 0 };
while (i <= m &&j <= n)
{
if (a[i] <= a[j])
{
tmp[k++] = a[i++];
}
else
{
tmp[k++] = a[j++];
}
}
while (i <= m)
{
tmp[k++] = a[i++];
}
while (j <= n)
{
tmp[k++] = a[j++];
}
for (i = 0; i<k; i++)
a[ l+i] = tmp[i];
}
void mergesort(int a[], int l, int r)
{
if (l < r)
{
int mid = (l + r) / 2;
mergesort(a, l, mid);
mergesort(a, mid + 1, r);
MergeArray(a, l, mid, r);
}
}
08基数排序
//(2)LSD法实现
//最低位优先法首先依据最低位关键码Kd对所有对象进行一趟排序,
//再依据次低位关键码Kd - 1对上一趟排序的结果再排序,
//依次重复,直到依据关键码K1最后一趟排序完成,就可以得到一个有序的序列。
//使用这种排序方法对每一个关键码进行排序时,不需要再分组,而是整个对象组。
#include<iostream>
#include<malloc.h>
using namespace std;
#define MAXSIZE 10000
#define N sizeof(br)/sizeof(*br)
int getdigit(int x, int d) //取数组内容的个位数字
{
int a[] = { 1, 10, 100 }; //最大三位数,所以这里只要百位就满足了。
return (x / a[d]) % 10; //依次取值个位 十位 百位
}
void PrintArr(int ar[], int n)
{
for (int i = 0; i < n; ++i)
{
cout << ar[i] << " ";
}
cout << endl;
}
void lsdradix_sort(int arr[], int begin, int end, int d)
{
const int radix = 10; //桶的个数不许修改
int count[radix], i, j;
int *bucket = (int*)malloc((end - begin + 1)*sizeof(int)); //所有桶的空间开辟//按照分配标准依次进行排序过程
for (int k = 1; k <= d; k++)//此处循环3次
{
for (i = 0; i < radix; i++) //置空
{count[i] = 0;}
for (i = begin; i <= end; i++) //统计编号为0-9的桶中所盛数据个数
{count[getdigit(arr[i], k)]++;}
for (i = 1; i < radix; i++) //count[i]表示第i个桶的右边界索引
{count[i] = count[i] + count[i - 1];} //这里应该是分别建立编号为0-9的右边界
//把数据依次装入桶(注意装入时候的分配技巧)
for (i = end; i >= begin; i--) //这里要从右向左扫描,保证排序稳定性
{
j = getdigit(arr[i], k); //求出关键码的第k位的数字
bucket[count[j] - 1] = arr[i];//这里是放到编号对应位置右边界依次往里面放
count[j]--; //对应桶的装入数据索引减一
}
//注意:此时count[i]为第i个桶左边界
//从各个桶中收集数据
for (i = begin, j = 0; i <= end; i++, j++)
{
arr[i] = bucket[j];
}
}
free(bucket);
}
void main()
{
int br[] = { 20, 80, 90,313,423,356,734, 998, 965, 852, 123, 456, 789 };
cout << "原数据如下:" << endl;
PrintArr(br, N);
lsdradix_sort(br, 0,N-1, 3); //数组+数组边界+数组位数
cout << "排序后数据如下:" << endl;
PrintArr(br, N);
}
排序思想:
例如按照低位排序,首先从左向右边统计0-9的数字个数。然后从左边向右边确定0-9数字在中间数组中的位置(确定右边界),然后从右边往左边遍历,放入桶中对应位置,右边界索引减1。然后把中间数组中的内容放到初始数组中。在释放中间数组
在申请数组的时候,得到一个连续类型的数据块和初始地址的时候,就可以按照数组的形式进行操作。
时间复杂度:d(n+r) d代表长度r代表关键字的基数。n代表关键字的个数
思路来源:网络上其他文章。
- C/C++ 八大排序算法
- C的八大排序法
- 八大排序算法C实现
- 八大排序算法代码C
- linux c 实现八大排序算法总结
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 八大排序
- 浅析this指针
- hibernate的一级缓存和二级缓存机制
- R
- VS 2010 显示行号,调整字体
- c++之虚函数与多态
- 八大排序 C++
- jni返回byte[]
- python中PIL的安装——转自脚本之家
- coresync配置
- 会话、前台进程组、后台进程组、孤儿进程等相关概念
- Eclipse jsp 运行tomcat提示端口占用错误
- ccf真题-201512-3-画图AC题解
- Oracle多种表连接方式
- jQuery中的fn是什么