c语言排序算法(所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序 )
来源:互联网 发布:天津mac口红专柜 编辑:程序博客网 时间:2024/06/06 02:58
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
2017.7.25记录排序算法。所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序
(归并排序、基数排序没有实现)
还需要增加的优化代码增加升序还是降序操作。
*/
//产生随机数组
void gen_array(int arr[],int n)
{
int i;
unsigned sr = time(NULL); //用当前时间做随机数种子
srand(sr); //初始化随机数
for(i=0;i<n;i++)
arr[i]=1+rand()%100;
}
void print(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%6d",a[i]);
printf("\n");
}
/*************************************************************************************************/
//传统冒泡排序 ,升序
void BubleSort(int a[],int n)
{
int i,j;
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
//冒泡排序改进1,添加标志位,如果某一次排序中出现没有交换位置,说明排序完成
void maopao1(int a[],int n)
{
int flag=0, i ,j;
for(i=0;i<n-1;i++)
{
flag=0;
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
flag=1;
}
if(flag==0)
break;
}
}
//冒泡排序改进2,添加标志位,记录最后一次交换位置的地方,证明最后一次交换位置之后的地方时排好序的,下一次只需要排最后一次之前的地方就好了
void maopao2(int a[],int n)
{
int flag=n-1;//刚开始,最后交换位置的地方设置为数组的最后一位
while(flag>0)//flag在逐渐减小,到最后肯定会变为0
{
int pos=0;//每一轮的最开始,标志位置在数组0
int i;
for(i=0;i<flag;i++)
if(a[i]>a[i+1])
{
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
pos=i;
}
flag=pos;
}
}
/*************************************************************************************************/
//冒泡改进3,传统冒泡每趟排序遍历一次找到一个最大值或者最小值,如果每趟遍历两次就会找打一个最大值和一个最小值,减少了一半的排序趟数
void maopao3( int r[], int n){
int low = 0;
int high= n -1; //设置变量的初始值
int tmp,j;
while (low < high) {
for (j= low; j< high; ++j) //正向冒泡,找到最大者
if (r[j]> r[j+1]) {
tmp = r[j]; r[j]=r[j+1];r[j+1]=tmp;
}
--high; //修改high值, 前移一位
for ( j=high; j>low; --j) //反向冒泡,找到最小者
if (r[j]<r[j-1]) {
tmp = r[j]; r[j]=r[j-1];r[j-1]=tmp;
}
++low; //修改low值,后移一位
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//快速排序
void QuickSort(int a[], int left, int right)
{
if (left < right)
{
int i = left, j = right, x = a[left];
while (i < j)
{
while(i < j && a[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
a[i++] = a[j];
while(i < j && a[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
a[j--] = a[i];
}
a[i] = x;
QuickSort(a, left, i - 1); // 递归调用
QuickSort(a, i + 1, right);
}
}
//快速排序
//第一个参数要排的数组,第二个参数第一个数,第三个参数数组成员个数
void kuaipai(int array[],int low,int hight)
{
int i,j,t,m;
if(low<hight)
{
i=low;
j=hight;
t=array[low];//第一个数为轴
while(i<j)
{
while(i<j && array[j]>t)//从右边找出小于轴的数
j--;
if(i<j)//将小于轴的数array[j]放到左边array[i]的位置
{
m=array[i];
array[i]=array[j];
array[j]=m;
i++;
}
while(i<j && array[i]<=t)//从左边找出大于轴的数
i++;
if(i<j)//将大于轴的数array[i]放在右边array[j]的位置
{
m=array[j];
array[j]=array[i];
array[i]=m;
j--;
}
}
array[i]=t;//轴放在中间,现在就有两个区域了分别是[0 i-1]和[i+1 hight],分别快排
kuaipai(array,0,i-1);
kuaipai(array,i+1,hight);
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//直接插入排序:将第一个数据看做一个顺序表,将后面的数据一次插入表中
void InsertSort(int a[], int n)
{
int i;
for(i= 1; i<n; i++){
if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
int j= i-1; //表中最后一个数据
int x = a[i]; //复制为哨兵,即存储待排序元素
a[i] = a[i-1]; //先后移一个元素 (因为a[i]就是X,所以不怕丢失)
while(j>=0 && x < a[j]){ //查找在有序表的插入位置 (遍历表)
a[j+1] = a[j];
j--; //元素后移
}
a[j+1] = x; //插入到正确位置
}
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//简单选择排序:遍历一次找到最小与第一个元素呼唤位置,再从第二个元素开始遍历找到最小与第二个元素呼唤位置...
void SelectSort(int a[],int n)
{
int i;
for(i=0;i<n-1;i++)
{
int k=i;//记录最小的那个下标的
int j;
for(j=i+1;j<n;j++)
if(a[j]<a[k])
k=j;
if(k!=i)
{
int t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//希尔排序:去增量为d1的分为一组,共分成d1组分别进行插入排序,然后每组对应元素放在一起,然后取d2...知道d=1
void ShellSort(int a[],int n)
{
int dk;
int tmp;
for(dk=n/2;dk>0;dk/=2)
{
int i;
for(i=dk;i<n;i++)
{
tmp=a[i];
int j;
for(j=i;j>=dk;j-=dk)
if(tmp<a[j-dk])
a[j]=a[j-dk];
else break;
a[j]=tmp;
}
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//首先可以看到堆建好之后堆中第0个数据是堆中最小的数据。取出这个数据再执行下堆的删除操作。这样堆中第0个数据又是堆中最小的数据,
//重复上述步骤直至堆中只有一个数据时就直接取出这个数据。
//由于堆也是用数组模拟的,故堆化数组后,第一次将A[0]与A[n - 1]交换,再对A[0…n-2]重新恢复堆。第二次将A[0]与A[n – 2]交换,
//再对A[0…n - 3]重新恢复堆,重复这样的操作直到A[0]与A[1]交换。由于每次都是将最小的数据并入到后面的有序区间,故操作完成后整个数组就有序了。有点类似于直接选择排序。
// 从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2
void HeapAdjust(int array[], int parent, int length) {
int temp = array[parent]; // temp保存当前父节点
int child = 2 * parent + 1; // 先获得左孩子
while (child < length) {
// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
if (child + 1 < length && array[child] < array[child + 1]) {
child++;
}
// 如果父结点的值已经大于孩子结点的值,则直接结束
if (temp >= array[child])
break;
// 把孩子结点的值赋给父结点
array[parent] = array[child];
// 选取孩子结点的左孩子结点,继续向下筛选
parent = child;
child = 2 * child + 1;
}
array[parent] = temp;
}
void HeapSort(int list[], int length) {
// 循环建立初始堆
int i;
for (i = length / 2; i >= 0; i--) {
HeapAdjust(list, i, length - 1);
}
// 进行n-1次循环,完成排序
for (i = length - 1; i > 0; i--) {
// 最后一个元素和第一元素进行交换
int temp = list[i];
list[i] = list[0];
list[0] = temp;
// 筛选 R[0] 结点,得到i-1个结点的堆
HeapAdjust(list, 0, i);
}
}
/*************************************************************************************************/
int main()
{
int array[10];
int len = sizeof(array)/sizeof(int);
int ch;
while(1)
{
gen_array(array,len);
printf("Original array:\n");
print(array,len);
printf("Please select sort method:\n");//显示菜单
printf("\t0 exit\n\t1 Buble sort\n\t2 Quick Sort\n\t3 Insertion Sort\n\t4 Selection Sort\n\t5 ShellSort\n\t6 HeapSort\nYour choice is>>");
scanf("%d",&ch);
switch(ch)
{
case 0:
return 0;
case 1:
BubleSort(array,len);
printf("Buble sorted array:\n");
print(array,len);
break;
case 2:
QuickSort(array,0,len-1);
printf("Quick sorted array:\n");
print(array,len);
break;
case 3:
InsertSort(array,len);
printf("Insertion sorted array:\n");
print(array,len);
break;
case 4:
SelectSort(array,len);
printf("Selection sorted array:\n");
print(array,len);
break;
case 5:
/* cin>>n;
int *a=new int[n+1];
for(int j=1;j<n;j++)//注意:这里是从1开始的
cin>>a[j];
HeapSort(a,n);
for(int i=1;i<n;i++)
cout<<a[i]; */
ShellSort(array,len);
printf("ShellSort sorted array:\n");
print(array,len);
break;
case 6:
HeapSort(array,len);
printf("HeapSort sorted array:\n");
print(array,len);
break;
case 7:
SelectSort(array,len);
printf("Selection sorted array:\n");
print(array,len);
break;
default:
break;
}
system("pause");
system("cls");
}
}
#include <stdlib.h>
#include <time.h>
/*
2017.7.25记录排序算法。所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序
(归并排序、基数排序没有实现)
还需要增加的优化代码增加升序还是降序操作。
*/
//产生随机数组
void gen_array(int arr[],int n)
{
int i;
unsigned sr = time(NULL); //用当前时间做随机数种子
srand(sr); //初始化随机数
for(i=0;i<n;i++)
arr[i]=1+rand()%100;
}
void print(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%6d",a[i]);
printf("\n");
}
/*************************************************************************************************/
//传统冒泡排序 ,升序
void BubleSort(int a[],int n)
{
int i,j;
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
//冒泡排序改进1,添加标志位,如果某一次排序中出现没有交换位置,说明排序完成
void maopao1(int a[],int n)
{
int flag=0, i ,j;
for(i=0;i<n-1;i++)
{
flag=0;
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
flag=1;
}
if(flag==0)
break;
}
}
//冒泡排序改进2,添加标志位,记录最后一次交换位置的地方,证明最后一次交换位置之后的地方时排好序的,下一次只需要排最后一次之前的地方就好了
void maopao2(int a[],int n)
{
int flag=n-1;//刚开始,最后交换位置的地方设置为数组的最后一位
while(flag>0)//flag在逐渐减小,到最后肯定会变为0
{
int pos=0;//每一轮的最开始,标志位置在数组0
int i;
for(i=0;i<flag;i++)
if(a[i]>a[i+1])
{
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
pos=i;
}
flag=pos;
}
}
/*************************************************************************************************/
//冒泡改进3,传统冒泡每趟排序遍历一次找到一个最大值或者最小值,如果每趟遍历两次就会找打一个最大值和一个最小值,减少了一半的排序趟数
void maopao3( int r[], int n){
int low = 0;
int high= n -1; //设置变量的初始值
int tmp,j;
while (low < high) {
for (j= low; j< high; ++j) //正向冒泡,找到最大者
if (r[j]> r[j+1]) {
tmp = r[j]; r[j]=r[j+1];r[j+1]=tmp;
}
--high; //修改high值, 前移一位
for ( j=high; j>low; --j) //反向冒泡,找到最小者
if (r[j]<r[j-1]) {
tmp = r[j]; r[j]=r[j-1];r[j-1]=tmp;
}
++low; //修改low值,后移一位
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//快速排序
void QuickSort(int a[], int left, int right)
{
if (left < right)
{
int i = left, j = right, x = a[left];
while (i < j)
{
while(i < j && a[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
a[i++] = a[j];
while(i < j && a[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
a[j--] = a[i];
}
a[i] = x;
QuickSort(a, left, i - 1); // 递归调用
QuickSort(a, i + 1, right);
}
}
//快速排序
//第一个参数要排的数组,第二个参数第一个数,第三个参数数组成员个数
void kuaipai(int array[],int low,int hight)
{
int i,j,t,m;
if(low<hight)
{
i=low;
j=hight;
t=array[low];//第一个数为轴
while(i<j)
{
while(i<j && array[j]>t)//从右边找出小于轴的数
j--;
if(i<j)//将小于轴的数array[j]放到左边array[i]的位置
{
m=array[i];
array[i]=array[j];
array[j]=m;
i++;
}
while(i<j && array[i]<=t)//从左边找出大于轴的数
i++;
if(i<j)//将大于轴的数array[i]放在右边array[j]的位置
{
m=array[j];
array[j]=array[i];
array[i]=m;
j--;
}
}
array[i]=t;//轴放在中间,现在就有两个区域了分别是[0 i-1]和[i+1 hight],分别快排
kuaipai(array,0,i-1);
kuaipai(array,i+1,hight);
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//直接插入排序:将第一个数据看做一个顺序表,将后面的数据一次插入表中
void InsertSort(int a[], int n)
{
int i;
for(i= 1; i<n; i++){
if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
int j= i-1; //表中最后一个数据
int x = a[i]; //复制为哨兵,即存储待排序元素
a[i] = a[i-1]; //先后移一个元素 (因为a[i]就是X,所以不怕丢失)
while(j>=0 && x < a[j]){ //查找在有序表的插入位置 (遍历表)
a[j+1] = a[j];
j--; //元素后移
}
a[j+1] = x; //插入到正确位置
}
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//简单选择排序:遍历一次找到最小与第一个元素呼唤位置,再从第二个元素开始遍历找到最小与第二个元素呼唤位置...
void SelectSort(int a[],int n)
{
int i;
for(i=0;i<n-1;i++)
{
int k=i;//记录最小的那个下标的
int j;
for(j=i+1;j<n;j++)
if(a[j]<a[k])
k=j;
if(k!=i)
{
int t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//希尔排序:去增量为d1的分为一组,共分成d1组分别进行插入排序,然后每组对应元素放在一起,然后取d2...知道d=1
void ShellSort(int a[],int n)
{
int dk;
int tmp;
for(dk=n/2;dk>0;dk/=2)
{
int i;
for(i=dk;i<n;i++)
{
tmp=a[i];
int j;
for(j=i;j>=dk;j-=dk)
if(tmp<a[j-dk])
a[j]=a[j-dk];
else break;
a[j]=tmp;
}
}
}
/*************************************************************************************************/
/*************************************************************************************************/
//首先可以看到堆建好之后堆中第0个数据是堆中最小的数据。取出这个数据再执行下堆的删除操作。这样堆中第0个数据又是堆中最小的数据,
//重复上述步骤直至堆中只有一个数据时就直接取出这个数据。
//由于堆也是用数组模拟的,故堆化数组后,第一次将A[0]与A[n - 1]交换,再对A[0…n-2]重新恢复堆。第二次将A[0]与A[n – 2]交换,
//再对A[0…n - 3]重新恢复堆,重复这样的操作直到A[0]与A[1]交换。由于每次都是将最小的数据并入到后面的有序区间,故操作完成后整个数组就有序了。有点类似于直接选择排序。
// 从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2
void HeapAdjust(int array[], int parent, int length) {
int temp = array[parent]; // temp保存当前父节点
int child = 2 * parent + 1; // 先获得左孩子
while (child < length) {
// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
if (child + 1 < length && array[child] < array[child + 1]) {
child++;
}
// 如果父结点的值已经大于孩子结点的值,则直接结束
if (temp >= array[child])
break;
// 把孩子结点的值赋给父结点
array[parent] = array[child];
// 选取孩子结点的左孩子结点,继续向下筛选
parent = child;
child = 2 * child + 1;
}
array[parent] = temp;
}
void HeapSort(int list[], int length) {
// 循环建立初始堆
int i;
for (i = length / 2; i >= 0; i--) {
HeapAdjust(list, i, length - 1);
}
// 进行n-1次循环,完成排序
for (i = length - 1; i > 0; i--) {
// 最后一个元素和第一元素进行交换
int temp = list[i];
list[i] = list[0];
list[0] = temp;
// 筛选 R[0] 结点,得到i-1个结点的堆
HeapAdjust(list, 0, i);
}
}
/*************************************************************************************************/
int main()
{
int array[10];
int len = sizeof(array)/sizeof(int);
int ch;
while(1)
{
gen_array(array,len);
printf("Original array:\n");
print(array,len);
printf("Please select sort method:\n");//显示菜单
printf("\t0 exit\n\t1 Buble sort\n\t2 Quick Sort\n\t3 Insertion Sort\n\t4 Selection Sort\n\t5 ShellSort\n\t6 HeapSort\nYour choice is>>");
scanf("%d",&ch);
switch(ch)
{
case 0:
return 0;
case 1:
BubleSort(array,len);
printf("Buble sorted array:\n");
print(array,len);
break;
case 2:
QuickSort(array,0,len-1);
printf("Quick sorted array:\n");
print(array,len);
break;
case 3:
InsertSort(array,len);
printf("Insertion sorted array:\n");
print(array,len);
break;
case 4:
SelectSort(array,len);
printf("Selection sorted array:\n");
print(array,len);
break;
case 5:
/* cin>>n;
int *a=new int[n+1];
for(int j=1;j<n;j++)//注意:这里是从1开始的
cin>>a[j];
HeapSort(a,n);
for(int i=1;i<n;i++)
cout<<a[i]; */
ShellSort(array,len);
printf("ShellSort sorted array:\n");
print(array,len);
break;
case 6:
HeapSort(array,len);
printf("HeapSort sorted array:\n");
print(array,len);
break;
case 7:
SelectSort(array,len);
printf("Selection sorted array:\n");
print(array,len);
break;
default:
break;
}
system("pause");
system("cls");
}
}
阅读全文
0 0
- c语言排序算法(所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序 )
- 排序算法----冒泡排序+插入排序+选择排序+快速排序+希尔排序+堆排序+归并排序+计数排序+基数排序+桶排序(c语言)
- C语言常用的排序方法:冒泡排序,插入排序,快速排序,堆排序,希尔排序
- C语言排序算法集锦:选择排序,冒泡排序,插入排序,希尔排序,归并排序,堆排序,快排序
- 基本的排序算法:冒泡排序、插入排序、希尔排序、选择排序、归并排序、快速排序、堆排序
- 算法导论之插入排序,选择排序,归并排序,冒泡排序,希尔排序,堆排序,快速排序的c语言实现
- 常用的排序算法:插入排序,希尔排序,冒泡排序,选择排序,快速排序,归并排序
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序,堆排序)
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序,堆排序)
- 排序算法: 冒泡排序, 快速排序,希尔排序,直接插入排序 ,直接选择排序,归并排序,堆排序
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 七种排序算法,包括:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序
- C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- 冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序java实现
- 插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序、归并排序
- 冒泡排序,插入排序,快速排序,归并排序,堆排序,选择排序,希尔排序
- 各种排序算法的稳定性(冒泡、选择、插入、快速、堆排序、希尔排序等)
- 博士生应慎读文献
- 基础篇-你应该知道的Activity
- 【java.lang.UnsupportedClassVersionError】版本不一致出错
- python 数据图表呈现
- AVL树C++实现
- c语言排序算法(所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序 )
- 9
- 位运算
- 字段自身+1 SQL语句
- [LeetCode] 636. Exclusive Time of Functions
- 搭建自己的基于motion移动物体的监控系统
- 解读支付宝实现的步骤
- Sublime Text2中文乱码问题
- Java源码阅读之HashMap