数据结构排序算法(代码实现)

一.插入排序法

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 }
View Code

四。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); // 最后归并起来
          }
}
View Code

 

posted @ 2019-10-31 03:55  徐大侠拯救世界  阅读(1623)  评论(0编辑  收藏  举报