堆排序:

 void HeapAdjust(int *arraydata,int rootnode,int len)
{
int j;
int t;
while(*rootnode+<len)
{
j=*rootnode+;
if ((j+)<len) //基右子树存在,则比较左右子树的大小
{
if(arraydata[j]<arraydata[j+]) //若左子树小于右子树,则调整为右子树于其双亲结点比较
{
j++;
}
}
if (arraydata[rootnode]<arraydata[j]) //若双亲结点小于兄弟结点,则进行交换
{
t=arraydata[rootnode];
arraydata[rootnode]=arraydata[j];
arraydata[j]=t;
rootnode=j; //堆被破坏,需要重新调整
}
else
break;
}
}
void HeapSort(int *data,int n)
{
int t,i;
int j;
for (i=n/-;i>=;i--)
{
HeapAdjust(data,i,n);
} for (int k=;k<n;k++)// 输出原始数据树建的堆数据
{
cout<<data[k]<<" ";
}
cout<<endl; for(i=n-;i>;i--)
{
t=data[];
data[]=data[i];
data[i]=t; for (int i=;i<n;i++) //输出交换后的数据,即将根结构的数据放到最后,使其成为有序序列
{
cout<<data[i]<<" ";
}
cout<<endl; HeapAdjust(data,,i); //将前i个数据重新构成堆 for (int i=;i<n;i++) //输出堆数据
{
cout<<data[i]<<" ";
}
cout<<endl;
}
}
int main(int argc,char* argv)
{
int b[]={,,,,,,,};
n=sizeof (b)/sizeof(b[]); for (int i=;i<n;i++)
{
cout<<b[i]<<",";
}
cout<<endl; HeapSort(b,n); for (int i=;i<n;i++)
{
cout<<b[i]<<",";
}
cout<<endl; return ;
}

参考资料:

数据结构堆排序篇

所谓堆和堆排序

堆排序算法,附图与C++代码

堆排序

堆排序基础讲解(代码+注释)

 void mybubble(int *a,int n)
{
if (NULL==a&&n<=)
{
printf("parameter error!\n");
} int i,j;
int temp;
for(i=;i<n-;i++) //控制外层循环,n个数需要n-1次
for(j=n-;j>=i;j--) //从后往前比较
//for(j=0;j<n-1-i;j++)//从前往后比较,控制内情循环,每次比较n-1-i次
{
if (a[j]>a[j+])//如果前一个数大于后一个数,则交换
{
temp=a[j];
a[j]=a[j+];
a[j+]=temp;
} } display(a,n); }
 #include <stdio.h>
/* 选择排序
插入排序
冒泡排序
希尔排序
堆排序
快速排序 */
////////////////////////////////////////////////////////
void SelectSort(int *a,int n)
{
int i,j;
int temp=;
int flag=; for (i=;i<n-;i++)
{
temp=a[i]; //暂存要比较的数
flag=i; //记录temp中存放数据的标号
for (j=i+;j<n;j++)//从i+1到n间的数据进行操作
{
if (a[j]<temp) //找出比a[i]中小的数据
{
temp=a[j];
flag=j;
}
} if (flag!=i)//将最小的数放入a[i]中
{
a[flag]=a[i];
a[i]=temp;
}
}
} /////////////////////////////////////////////////////
void InsertSort(int *a,int n)
{
int i,j;
int temp;
for (i=;i<n;i++)
{
temp=a[i]; //暂存当前比较的数
for (j=i-;j>=;j--)//从i-1到0间的数据进行操作
{
if (temp<a[j]) //检查是否有插入的可能
{
a[j+]=a[j];
}
else
break;
} a[j+]=temp;//最后插入
}
} //////////////////////////////////////////////////
void BubbleSort(int *a,int n)
{
int i,j;
int temp;
for (i=;i<n-;++i)
{
for (j=n-;j>i;--j)//从n-1到i,即从前到后,将最小的值放到前面
{
if (a[j]<a[j-])
{
temp=a[j];
a[j]=a[j-];
a[j-]=temp;
}
}
}
} /////////////////////////////////////////////////////
void ShellSort(int *a,int n)
{
int i,j;
int step;
int temp; for (step=n/;step>;step=step/) //第k趟排序
{
for (i=step;i<n;i++)
{
temp=a[i];
for (j=i-step;j>=;j-=step)
{
if (temp<a[j])
{
a[j+step]=a[j];
}
else
break;
}
a[j+step]=temp;
}
} }
/////////////////////////////////////////////////
void AdjustMinHeap(int *a,int pos,int len)
{
int temp;
int child; for (temp=a[pos];*pos+<=len;pos=child)
{
child=*pos+;
if (child<len&&a[child]>a[child+])
{
child++;
}
if (a[child]<temp)
{
a[pos]=a[child];
}
else
break;
}
a[pos]=temp;
} void MinHeapSort(int *a,int len)
{
int i;
int temp;
for (i=len/-;i>=;i--)
{
AdjustMinHeap(a,i,len-);
}
for (i=len-;i>=;i--)
{
temp=a[];
a[]=a[i];
a[i]=temp;
AdjustMinHeap(a,,i-);
}
} void AdjustMaxHeap(int *a,int pos,int len)//生成大根堆
{
while((*pos+)<len)
{
int m=*pos+;
if((*pos+)<len)
{
if(a[*pos+]<a[*pos+])
m=*pos+;
}
if (a[pos]<a[m]) //堆被破坏,需要调整
{
int tempData=a[pos]; //交换数据
a[pos]=a[m];
a[m]=tempData; pos=m;
}
else
break; //堆未破坏,无需调整
}
} void MaxHeapSort(int *a,int len)
{
int i=; for (i=len/-;i>=;i--) //将数组建成大根堆
{
AdjustMaxHeap(a,i,len);
} for (i=len-;i>;i--)
{
int temp=a[]; //与最后一个记录交换
a[]=a[i];
a[i]=temp; AdjustMaxHeap(a,,i);//重新将数据调整为大根堆
}
}
//////////////////////////////////////////////////
void QuickSort(int *a,int left,int right)
{
int i,j,temp;
i=left;
j=right;
temp=a[left];
if (left>right)
{
return;
} while(i!=j)
{
while(a[j]>=temp&&j>i)
{
j--;
} if (j>i) //将大值放于后面
{
a[i++]=a[j];
} while (a[i]<=temp&&j>i)
{
i++;
} if(j>i) //将小值放于前面
{
a[j--]=a[i]; }
} a[i]=temp;
QuickSort(a,left,i-);
QuickSort(a,i+,right);
} ////////////////////////////////////////////////
int main()
{ int i=;
int a[]={,,,,,,};
int len=sizeof(a)/sizeof(a[]); for(i=;i<len;i++)
printf("%d ",a[i]);
printf("\n"); // SelectSort(a,len);
// BubbleSort(a,len);
// InsertSort(a,len);
// ShellSort(a,len);
// MinHeapSort(a,len);
// MaxHeapSort(a,len);
QuickSort(a,,len-); for(i=;i<len;i++)
printf("%d ",a[i]);
printf("\n"); return ;
}
 #include <iostream>

 using namespace std;

 void display(int a[],int len)
{
for(int i=;i<len;i++)
{
printf("%d ",a[i]);
}
printf("\n"); } //插入排序
void insert(int *a,int n)
{
int i,j,temp; for(i=;i<;i++) /*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/
{
temp=a[i]; /*将待插入数暂存于变量t中*/
for( j=i- ; j>= && temp<a[j] ; j-- ) /*在有序序列(下标0 ~ i-1)中寻找插入位置*/
a[j+]=a[j]; /*若未找到插入位置,则当前元素后移一个位置*/
a[j+]=temp; /*找到插入位置,完成插入*/
}
display(a,n);
}
//希尔排序
void shellSort(int a[],int len)
{
int step;
int i,j;
int temp;
for(step=len/; step>;step/=) //用来控制步长,最后递减到1
{
// i从第step开始排列,应为插入排序的第一个元素
// 可以先不动,从第二个开始排序
for(i=step;i<len;i++)
{
temp = a[i];
for(j=i-step;(j>= && temp < a[j]);j-=step)
{
a[j+step] = a[j];
}
a[j+step] = temp; //将第一个位置填上
} }
display(a,len);
}
//选择排序
void choise(int *a,int n)
{
int i,j,k,temp;
for(i=;i<n-;i++) /*外循环控制趟数,n个数选n-1趟*/
{
k=i; /*假设当前趟的第一个数为最值,记在k中 */
for(j=i+;j<n;j++) /*从下一个数到最后一个数之间找最值*/
if(a[k]>a[j]) /*若其后有比最值更大的*/
k=j; /*则将其下标记在k中*/ if(i!=k) /*若k不为最初的i值,说明在其后找到比其更大的数*/
{ /*则交换最值和当前序列的第一个数*/
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
display(a,n);
}
//堆排序
/*假设节点i的左右子树都是最大堆,操作使节点i的子树变成最大堆*/
void maxHeap(int A[],int len,int i)
{
int l,r,large,temp;
l=*i;
r=*i+;
large=i;
if(l<len)
{
if(A[l]>A[i])
{
large=l;
}
}
if(r<len)
{
if(A[r]>A[large])
{
large=r;
}
} if(large!=i)
{
temp=A[large];
A[large]=A[i];
A[i]=temp;
maxHeap(A,len,large);
}
} /*建立大根堆*/
void buildMaxHeap(int A[],int len)
{
int i;
for(i=len/-;i>=;i--)
maxHeap(A,len,i);
} /*堆排序*/
void maxHeapSort(int A[],int len)
{
int i,temp;
buildMaxHeap(A,len);
printf("建立大跟堆\n");
for(i=;i<len;i++)
printf("%d ",A[i]);
printf("\n"); for(i=len;i>;i--)
{
temp=A[];
A[]=A[i-];
A[i-]=temp;
printf("%d ",A[i-]);
buildMaxHeap(A,i-);
}
printf("\n");
}
//冒泡排序
void bubble(int *a,int n) /*定义两个参数:数组首地址与数组大小*/
{
int i,j,temp;
for(i=;i<n-;i++) /*外循环控制排序趟数,n个数排n-1趟 */
for(j=;j<n--i;j++) /*内循环每次比较的次数,第i次比较n-i次*/
if(a[j]>a[j+]) //相信元素比较,逆序则交换
{
temp=a[j];
a[j]=a[j+];
a[j+]=temp;
}
display(a,n);
}
//快速排序
void quick_sort(int *arr, int begin, int end)
{
char pivot = arr[begin];
int i,j;
i = begin;
j = end;
while(i < j)
{
while(arr[j] >= pivot && i < j)
j --;
arr[i] = arr[j];
while(arr[i] <= pivot && i < j)
i ++;
arr[j] = arr[i];
}
arr[i] = pivot;
if( i- > begin)
quick_sort(arr, begin, i - );
if( end > i + )
quick_sort(arr, i + , end); //display(arr,end+1);
}
//基数排序
#define GET_MASK_VALUE(x, mask, shift) (((x) & mask) >> (shift))
int find_max(int array[], int len, int mask, int shift)
{
int i = ;
int max = GET_MASK_VALUE(array[i], mask, shift); for (i = ; i < len; i++) {
if (GET_MASK_VALUE(array[i], mask, shift) > max)
max = GET_MASK_VALUE(array[i], mask, shift);
} return max;
} void count_sort(int array[], int sort[], int len, int mask, int shift)
{
int i, max;
int *temp = NULL; max = find_max(array, len, mask, shift); printf("mask:%-8x shift:%d\n", mask, shift); temp = (int *)malloc((max + )* sizeof(int));
if (temp == NULL) {
return;
} memset(temp, , sizeof(int) * (max + )); for (i = ; i < len; i++) {
temp[GET_MASK_VALUE(array[i], mask, shift)]++;
} for (i = ; i <= max; i++) {
temp[i] += temp[i-];
} for (i = (len - ); i >= ; i--) {
sort[temp[GET_MASK_VALUE(array[i], mask, shift)]-] = array[i];
temp[GET_MASK_VALUE(array[i], mask, shift)]--;
}
} void radix_sort(int array[], int len, int digit_bits, int bit_width)
{
int i = ;
int *sort = NULL;
int cycles = , shift = ;
unsigned int mask = ;
unsigned int initmask = ( << bit_width) - ; sort = (int *)malloc(sizeof(int) * len);
if (sort == NULL)
return; memset(sort, , sizeof(int) * len); cycles = digit_bits / bit_width; for (i = ; i < cycles; i++) {
mask = initmask << (i * bit_width);
shift = i * bit_width;
count_sort(array, sort, len, mask, shift);
memcpy(array, sort, sizeof(int) * len);
} return;
} void main(void)
{ const int Asize=;
printf("------------插入排序-----------------------\n");
int a[]={,,,,,,,,};
display(a,);
insert(a,); printf("------------希尔排序-------------------------\n");
int b[]={,,,,,,,,};
display(b,);
shellSort(b,); printf("------------冒泡排序-------------------------\n");
int c[]={,,,,,,,,};
display(c,);
bubble(c,); printf("------------快速排序-------------------------\n");
int d[]={,,,,,,,,};
display(d,);
quick_sort(d,,);
display(d,); printf("------------选择排序------------------------\n");
int e[]={,,,,,,,,};
display(e,);
choise(e,); printf("------------堆排序-------------------------\n");
int f[]={,,,,,,,,};
display(f,);
maxHeapSort(f,);
display(f,); printf("------------基数排序---------------------\n");
int g[]={,,,,,,,,};
display(g,);
radix_sort(g,,sizeof(int)*,);
display(g,); }

一、冒泡法:

基本思想:如果有n个数,则要进行n-1趟比较。在第1趟比较中要进行n-1次相邻元素的两两比较,在第j趟比较中要进行n-j次两两比较。比较的顺序从前往后,经过一趟比较后,将最值沉底(换到最后一个元素位置),最大值沉底为升序,最小值沉底为降序。

相邻元素两两比较,每趟将最值沉底即可确定一个数在结果的位置,确定元素位置的顺序是从后往前,其余元素可能作相对位置的调整。可以进行升序或降序排序。

源代码:

 void bubble(int *a,int n) /*定义两个参数:数组首地址与数组大小*/
{
int i,j,temp;
for(i=;i<n-;i++) /*外循环控制排序趟数,n个数排n-1趟 */
for(j=;j<n--i;j++) /*内循环每次比较的次数,第i次比较n-i次*/
if(a[j]>a[j+]) //相信元素比较,逆序则交换
{
temp=a[j];
a[j]=a[j+];
a[j+]=temp;
}
}

优点:稳定,比较次数已知;

缺点:慢,每次只能移动相邻两个数据,移动数据的次数多。

二、选择排序

基本思想:每趟选出一个最值和无序序列的第一个数交换,n个数共选n-1趟。第i趟假设i为最值下标,然后将最值和i+1至最后一个数比较,找出最值的下标,若最值下标不为初设值,则将最值元素和下标为i的元素交换。

每趟是选出一个最值确定其在结果序列中的位置,确定元素的位置是从前往后,而每趟最多进行一次交换,其余元素的相对位置不变。可进行降序排序或升序排序。

定义外部n-1次循环,假设第一个为最值,放在参数中,在从下一个数以后找最值若后面有比前面假设的最值更大的就放在k中,然后在对k进行分析。若k部位最初的i值。也就是假设的i不是最值,那么就交换最值和当前序列的第一个数

测试代码:

 void choise(int *a,int n)
{
int i,j,k,temp;
for(i=;i<n-;i++) /*外循环控制趟数,n个数选n-1趟*/
{
k=i; /*假设当前趟的第一个数为最值,记在k中 */
for(j=i+;j<n;j++) /*从下一个数到最后一个数之间找最值*/
if(a[k]>a[j]) /*若其后有比最值更大的*/
k=j; /*则将其下标记在k中*/ if(i!=k) /*若k不为最初的i值,说明在其后找到比其更大的数*/
{ /*则交换最值和当前序列的第一个数*/
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
}

优点:稳定,比较次数与冒泡排序一样,数据移动次数比冒泡排序少;

缺点:相对之下还是慢。

三、插入排序

基本思想:将序列分为有序序列和无序列,依次从无序序列中取出元素值插入到有序序列的合适位置。初始是有序序列中只有第一个数,其余n-1个数组成无序序列,则n个数需进n-1次插入。寻找在有序序列中插入位置可以从有序序列的最后一个数往前找,在未找到插入点之前可以同时向后移动元素,为插入元素准备空间。

每趟从无序序列中取出第一个数插入到有序序列的合适位置,元素的最终位置在最后一趟插入后才能确定位置。也可是先用循环查找插入位置(可从前往后或从后往前),再将插入位置之后的元素(有序列中)逐个后移一个位置,最后完成插入。该算法的特点是在寻找插入位置的同时完成元素的移动。因为元素的移动必须从后往前,则可将两个操作结合在一起完成,提高算法效率。仍可进行升序或降序排序。 

算法实现:假设待排序的元素有n个,对应的关键字分别是a1,a2,..an,因为第1个元素是有序的,所以从第2个元素开始,将a2与a1进行比较,如果a2<a1,则将a2插入到a1之前;否则,说明已经有序,不需要移动a2,这样有序的元素个数变为2.然后将a3与a1和a2进行比较,确定a3的位置。首先将a3与a2进行比较,如果a3>=a2,则说明a1 a2,a3已经是有序排序。如果a3<a2,则继续将a3与a1比较,如果a3<a1,则将a3插入到a1之前,否则,将a3插入到a1与a2之间,即完成了a1,a2,a3的排列。依次类推,直到最后一个关键字an插入到n-1个有序排列。

测试代码:

 void insert(int *a,int n)
{
int i,j,temp; for(i=;i<;i++) /*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/
{
temp=a[i]; /*将待插入数暂存于变量t中*/
for( j=i- ; j>= && temp<a[j] ; j-- ) /*在有序序列(下标0 ~ i-1)中寻找插入位置*/
a[j+]=a[j]; /*若未找到插入位置,则当前元素后移一个位置*/
a[j+]=temp; /*找到插入位置,完成插入*/
} }

优点:稳定,快;

缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。

四、快速排序

基本思想:

测试代码:

优点:极快,数据移动少;

缺点:不稳定。

C语言中的七种排序算法的更多相关文章

  1. 模板化的七种排序算法,适用于T* vector<T>以及list<T>

    最近在写一些数据结构以及算法相关的代码,比如常用排序算法以及具有启发能力的智能算法.为了能够让写下的代码下次还能够被复用,直接将代码编写成类模板成员函数的方式,之所以没有将这种方式改成更方便的函数模板 ...

  2. 数据结构(三) 用java实现七种排序算法。

    很多时候,听别人在讨论快速排序,选择排序,冒泡排序等,都觉得很牛逼,心想,卧槽,排序也分那么多种,就觉得别人很牛逼呀,其实不然,当我们自己去了解学习后发现,并没有想象中那么难,今天就一起总结一下各种排 ...

  3. php中的四种排序算法

    . 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将 ...

  4. 用 C 语言描述几种排序算法

    排序算法是最基本且重要的一类算法,本文基于 VS2017,使用 C 语言来实现一些基本的排序算法. 一.选择排序 选择排序,先找到数组中最小的元素,然后将这个元素与数组的第一个元素位置互换(如果第一个 ...

  5. 学习Java绝对要懂的,Java编程中最常用的几种排序算法!

    今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来!     ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...

  6. 史上最全单链表的增删改查反转等操作汇总以及5种排序算法(C语言)

    目录 1.准备工作 2.创建链表 3.打印链表 4.在元素后面插入元素 5.在元素前面增加元素 6.删除链表元素,要注意删除链表尾还是链表头 7.根据传入的数值查询链表 8.修改链表元素 9.求链表长 ...

  7. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  8. 我们一起来排序——使用Java语言优雅地实现常用排序算法

    破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...

  9. 排序—时间复杂度为O(n2)的三种排序算法

    1 如何评价.分析一个排序算法? 很多语言.数据库都已经封装了关于排序算法的实现代码.所以我们学习排序算法目的更多的不是为了去实现这些代码,而是灵活的应用这些算法和解决更为复杂的问题,所以更重要的是学 ...

随机推荐

  1. spring mvc 使用Optional

    return Optional.ofNullable(brokerRepository.findOne(id)) .map(broker -> new ResponseEntity<> ...

  2. python(6)-shutil模块

    高级的 文件.文件夹.压缩包 处理模块 shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中: #源码 def copyfileobj(fsr ...

  3. Linux学习之路:命令别名、历史记录和命令查找执行顺序

    一.命令别名 alias rm='rm –i':删除命令时会随时出现提示;alias vi=vim alias 不加参数,显示系统内所以命令别名 unalias 取消别名 二.历史命令 history ...

  4. [改善Java代码]在接口中不要存在实现代码

    第3章  类.对象及方法 书读得多而不思考,你会觉得自己知道的很多. 书读得多而思考,你会觉得自己不懂的越来越多. —伏尔泰 在面向对象编程(Object-Oriented Programming,O ...

  5. 【原创】 windows下开发软件推荐

    1. 数据库查看器工具 navicat.exe

  6. ubuntu共享文件夹给virtualbox

    在ubuntu或者linuxmint等linux系统下安装了virtualbox,可以通过共享文件夹的方式,把文件夹共享给virtualbox下的虚拟机系统,我这里的虚拟机系统是win7,共享过程如下 ...

  7. PLSQL插入数据中文乱码的问题

    PLSQL插入数据中文乱码的问题 中文乱码就是编码不统一所导致的了,解决办法只需要把编码统一下即可解决了. 具体操作步骤如下: 1.查看服务器端编码 select userenv('language' ...

  8. 第三篇、微信小程序-网络请求API

    wx.request(OBJECT)发起的是https请求.一个微信小程序,同时只能有5个网络请求连接. OBJECT参数说明: 效果图: net.js Page({ data:{ result:{} ...

  9. 【原】从/dev/null重新打开标准输出

    今天遇到一个程序,使用了printf输出中间的信息,我也懒得去改.由于此进程被其他进程fork之后,dup2 了标识输入输出到了/dev/null,再通过execvp装载进来.于是,为了看到输出的信息 ...

  10. CodeBlock使用技巧

    CodeBlock是一款采用C++编写的完全开源.功能强大的IDE,工欲善其事必先利其器,为了更加方便后期的开发调试,下面先就网上的一些 官方主页地址为:    http://www.codebloc ...