數據結構排序算法(代碼實現)


一.插入排序法

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM