数据结构排序算法(代码实现)
一.插入排序法
1.直接插入法排序,C语言实现。
算法思想:略
int main() {
int A[]={1,9,4,6,8,10,7};
int i,j,la;
la =sizeof(A)/sizeof(A[0]);
for(i=1;i<la;i++){ //从数组下标为1的开始,也即从第二个元素开始,因为初始假设A[0]为有序的子序列
int temp=A[i]; //保存插入元素的临时变量
for(j=i-1;j>=0&&A[j]>temp;j--){ //将要插入的第i个元素与第j个元素比较(即与上一个元素比较大小)
//第i个元素比第j个元素小,则进入循环(即查找插入位置)。(默认是递增序列排序)
A[j+1]=A[j];//将第j个元素至i-1个元素依次后移动一个位置(即将较大的元素后移一个位置)
}
A[j+1]=temp;//将要插入的元素插入j+1的位置(j+1就是需要找的插入位置)。
}
for(int a = 0; a<la;a++){
printf("%d,",A[a]);
}
return 0;
}
2.折半插入排序法,C语言实现
算法思想:略
int main() {
int A[]={15,9,4,6,8,10,11};
int i,j,la,low,high,mid;
la =sizeof(A)/sizeof(A[0]);
for(i=1;i<la;i++){
int temp=A[i]; //保存插入元素的临时变量
low=0; high=i-1; // 确定折半查找范围
while(low<=high){ // 递增有序查找
mid=(low+high)/2; // 寻找中间元素,向下取整
if(A[mid]>temp){
high=mid-1;//中间位置的元素大于第i个位置的元素,则high=mid-1即
//第i个元素会将插入到high+1的位置。
}else{
low=mid+1;//否则移动low后,再此进入while循环。
}
}
for(j=i-1;j>=high+1;j--){//上面确定好位置后,现在移动元素位置,从第high+1个元素到i-1个元素依次序
//往后移动i一位
A[j+1]=A[j];
}
A[high+1]=temp;//最后将第i个元素存储的临时变量值赋予给第high+1个位置,即插入元素
}
for(int a = 0; a<la;a++){
printf("%d,",A[a]);
}
return 0;
}
3.希尔排序
二.交换排序
1.冒泡排序
int main() {
int A[]={10,23,20,2,1};
int i,j,la,temp;
la =sizeof(A)/sizeof(A[0]); //获取数组长度
for(i=0;i<la;i++){ //排序次数为数组长度-1
int flag=0; //排序结束标志位
for(j=la-1;j>i;j--){ //每次排序的比较次数为:数组la-1,循环逐渐递减
if(A[j-1]>A[j]){ //满足条件交换(递增排序)
temp=A[j-1];
A[j-1]=A[j];
A[j]=temp;
flag=1; //交换完成后标志位置1
}
}
if(flag==0){ //若标志位为零,则上一次没有发生交换,说明有序,打印出排序结果,结束排序。
printf("第%d趟排序结果:",i+1);
for(int a = 0; a<la;a++){
printf("%d,",A[a]);
}
printf("\n");
return 0; //结束排序
}
}
}
2.快速排序
#include <stdio.h> void QuickSort(int A[],int low,int high); int Partition(int A[],int low,int high); int main() { int A[]={5,7,3,9,6,2}; int la =sizeof(A)/sizeof(A[0]); int low=0; int high=la-1; QuickSort(A,low,high); //int b=Partition(A,low,high); //printf("%d",b); //printf("\n"); for(int a = 0; a<la;a++){ printf("%d,",A[a]); } } void QuickSort(int A[],int low,int high){ if(low<high){ int pivotpos = Partition(A,low,high); //一次划分操作 QuickSort(A, low, pivotpos-1); //左边部分 QuickSort(A,pivotpos+1, high); //右边部分 } } int Partition(int A[],int low,int high){ //一次划分操作 //int l;l=low; //int h;h=high; int piovt = A[low]; //以第一个元素作为划分基准 while(low<high){ while (low<high&&piovt<=A[high]){--high;}//比较是从high位置开始向前比较,遇到比基准元素大的,就不动,--h依次比较, A[low]=A[high];//遇到比基准元素小的则放在左边。 while(low<high&&piovt>=A[low]){++low;}// A[high]=A[low];//遇到比基准元素大的则放在右边。 } A[low]=piovt; return low; //返回基准元素的最终位置,进行下一比较。 }
三.选择排序
1.简单选择排序
int main() {
int A[]={10,23,20,2,1};
int i,j,la,min,temp;
la =sizeof(A)/sizeof(A[0]);
for(i=0;i<la;i++){
min=i;
for(j=i+1;j<la;j++){
if(A[j]<A[min]){
min=j;
}
}
if(min!=i){
temp=A[i];
A[i]=A[min];
A[min]=temp;
}
printf("第%d趟排序结果:",i+1);
for(int a = 0; a<la;a++){
printf("%d,",A[a]);
}
printf("\n");
}
}
2.堆排序(大根堆,建堆过程)
1 #include <stdio.h> 2 void AdjustDown(int a[],int k,int len); 3 //void AdjustUp(int a[],int k); 4 int main() { 5 6 int A[]={53,17,78,9,45,65,87,32}; 7 int len=sizeof(A)/sizeof(A[0]); 8 for(int i=(len/2)-1;i>=0;i--){ 9 AdjustDown(A,i,len); 10 } 11 for(int a=0;a<len;a++){ 12 printf("%d,",A[a]); 13 14 } 15 /*for(int k=len-1;k>=0;k--){ 16 AdjustUp(A,k); 17 } 18 for(int a=0;a<len;a++){ 19 printf("%d,",A[a]); 20 21 }*/ 22 23 } 24 void AdjustDown(int a[],int k,int len){ 25 int temp=a[k]; //将第k个元素(即完全二叉树最后一个节点的双亲节点位置k=(len/2)-1,向下取整 26 for(int i=k*2+1;i<=len;i=i*2+1){//依次对a[(len/2)-1]个节点h至a[0]个节点为根与左右孩子节点比较 27 if(i<len&&a[i]<a[i+1]){//右孩子与左孩子比较,i<len是防止数组下标越界,取较大的孩子节点的下标 28 i++; //右孩子节点值大取右孩子节点下标。 29 } 30 if(temp>=a[i]){//如果根节点大于较大孩子节点,则跳出循环 31 break ; 32 }else{//否则将根节点与较大孩子孩子节点交换位置。 33 a[k]=a[i]; 34 k=i;//因为交换后可能会破坏完全二叉树结构,所以将i给k(不太好说),继续向下调整。 35 } 36 } 37 a[k]=temp;//将调整好节点放入最终位置 38 }
四。2路归并排序
#include <stdio.h> #include <stdlib.h> void Merge(int A[],int low,int mid,int high); void MergeSort(int A[],int low,int high); int main(){ int A[]={22,33,11,44,66,55}; int len =sizeof(A)/sizeof(A[0]); //int *B=(int *)malloc(len*sizeof(int)); int low=0;int high=len-1; MergeSort(A,low,high); for(int a = 0; a<len;a++){ printf("%d,",A[a]); } } void Merge(int A[],int low,int mid,int high){ int *B=(int *)malloc(6*sizeof(int));//辅助数组B,6是数组长度,分配6个字节内存单元。 //int B[]={}; int i,j,k; for(k=low;k<=high;k++){ B[k]=A[k]; //现将A全部复制到B中。 } for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){ //在B中比较A[low]~A[mid]与A[mid+1]~A[high]的大小,将较小的先复制到A中。 if(B[i]<B[j]){ A[k]=B[i++]; }else{ A[k]=B[j++]; } } while(i<=mid){A[k++]=B[i++];}// 如果A的左边在B中没有复制完,全部复制到A中。 while(j<=high){A[k++]=B[j++];}// 若果A的右边在B中没有复制完,全部复制到A中 } void MergeSort(int A[],int low,int high){ if(low<high){ int mid=(low+high)/2; //先拆开 MergeSort(A,low,mid); // 拆左边 MergeSort(A, mid+1, high); // 拆右边 Merge(A, low, mid, high); // 最后归并起来 } }