C/C++ 常用排序算法整理匯總分享
(偽)冒泡排序算法:
相鄰的兩個元素之間,如果反序則交換數值,直到沒有反序的記錄為止.
#include <stdio.h> void BubbleSort(int Array[], int ArraySize) { int x, y, temporary; for (x = 0; x < ArraySize - 1; x++) { for (y = x + 1; y < ArraySize; y++) { if (Array[x] > Array[y]) { temporary = Array[y]; Array[y] = Array[x]; Array[x] = temporary; } } } } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; BubbleSort(a, 10); for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } system("pause"); return 0; }
(真)冒泡排序算法:
正宗的冒泡排序就是從下往上兩兩比較,所以看上去就像是泡泡向上冒一樣.
#include <stdio.h> void BubbleSort(int Array[], int ArraySize) { int x, y, temporary; for (x = 0; x < ArraySize - 1; x++) { for (y = ArraySize - 1; y > x; y--) { if (Array[y-1] > Array[y]) { temporary = Array[y-1]; Array[y-1] = Array[y]; Array[y] = temporary; } } } } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; BubbleSort(a, 10); for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } system("pause"); return 0; }
選擇排序算法:
該算法通過Array-x次關鍵字比較,從Array-x+1個記錄中選出關鍵字最小的記錄,並和第x個記錄交換.
#include <stdio.h> void SelectSort(int Array[], int ArraySize) { int x, y, minimum, temporary; for (x = 0; x < ArraySize - 1; x++) { minimum = x; // 假設x是最小的數 for (y = x + 1; y < ArraySize; y++) { // 將假設中的最小值進行比對 if (Array[y] < Array[minimum]) minimum = y; } if (minimum != x) { // 循環結束後進行交換 temporary = Array[minimum]; Array[minimum] = Array[x]; Array[x] = temporary; } } } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; SelectSort(a, 10); for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } system("pause"); return 0; }
直接插入排序:
該算法將一個記錄插入到已經排好序的有序表中,從而得到一個新的,記錄數增加1的有序表.
#include <stdio.h> void InsertSort(int Array[], int ArraySize) { int x, y, temporary; for (x = 1; x < ArraySize; x++) { if (Array[x] < Array[x - 1]) { temporary = Array[x]; // 把小的元素放入temp for (y = x - 1; Array[y] > temporary; y--) { Array[y + 1] = Array[y]; } Array[y + 1] = temporary; } } } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; InsertSort(a, 10); for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } system("pause"); return 0; }
(分組)希爾排序:
在直接插入排序進行升級,把記錄進行分組,分割成若幹個子序列,把每一個子序列分別進行插入排序.
#include <stdio.h> void ShellSort(int Array[], int ArraySize) { int x, y, temporary; int interval = ArraySize; // 設置排序間隔 do { interval = interval / 3 + 1; for (x = interval; x < ArraySize; x++) { if (Array[x] < Array[x - interval]) { temporary = Array[x]; // 把小的元素放入temp for (y = x - interval; Array[y] > temporary; y -= interval) { Array[y + interval] = Array[y]; } Array[y + interval] = temporary; } } } while (interval > 1); } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; ShellSort(a, 10); for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } system("pause"); return 0; }
歸並排序算法:
將數組拆分成兩部分,然後將每部分再次拆成兩部分,直到無法拆瞭為止,然後兩兩比較,最後在歸並到一起.
#include <stdio.h> #define MAXSIZE 10 // 實現歸並,並把最後的結果存放到list1裡面 void merging(int *list1,int list1_size,int *list2,int list2_size) { int list1_sub = 0, list2_sub = 0, k = 0; int temporary[MAXSIZE]; while (list1_sub < list1_size && list2_sub < list2_size) { if (list1[list1_sub] < list2[list2_sub]) temporary[k++] = list1[list1_sub++]; else temporary[k++] = list2[list2_sub++]; } while (list1_sub < list1_size) temporary[k++] = list1[list1_sub++]; while (list2_sub < list2_size) temporary[k++] = list2[list2_sub++]; // 最後將歸並後的結果存入到list1變量中 for (int m = 0; m < (list1_size + list2_size); m++) list1[m] = temporary[m]; } // 拆分數組,拆分以後傳入merging函數實現歸並 void MergeSort(int Array[], int ArraySize) { // 如果大於1則終止拆解數組 if (ArraySize > 1) { int *list1 = Array; // 左邊部分 int list1_size = ArraySize / 2; // 左邊的尺寸,每次是n/2一半 int *list2 = Array + ArraySize / 2; // 右半部分,就是左半部分的地址加上右半部分的尺寸 int list2_size = ArraySize - list1_size; // 右半部分尺寸 MergeSort(list1, list1_size); // 遞歸拆解數組1 MergeSort(list2, list2_size); // 遞歸拆解數組2 merging(list1, list1_size, list2, list2_size); // 歸並 } } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; MergeSort(a, 10); for (int i = 0; i < 10; i++) printf("%d ", a[i]); system("pause"); return 0; }
迭代歸並排序:
代碼指針存在問題.
#include <stdio.h> #include <stdlib.h> void MergeSort(int k[], int n) { int i, left_min, left_max, right_min, right_max; // 申請臨時空間 int *temp = (int *)malloc(n * sizeof(int)); for (i = 1; i < n; i *= 2) // i => 步長,每次對比兩個元素 { for (left_min = 0; left_min < n - i; left_min = right_max) { right_min = left_max = left_min + i; right_max = left_max + i; if (right_max > n) // 有時數組無法整除,我們來處理一下 { right_max = n; } int next = 0; while (left_min < left_max && right_min < right_max) { if (k[left_min] < k[right_min]) { temp[next++] = k[left_min]; } else { temp[next++] = k[right_min]; } } while (left_min < left_max) { k[--right_min] = k[--left_min]; } while (next >0) { k[--right_min] = temp[--next]; } } } } int main(int argc, char* argv[]) { int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 }; MergeSort(a, 10); for (int i = 0; i < 10; i++) printf("%d ", a[i]); system("pause"); return 0; }
迭代歸並排序2:
代碼指針存在問題.
#include <stdio.h> #include <stdlib.h> // 定義鏈表節點類型 struct LinkNode { int data; struct LinkNode *next; }; struct LinkNode *init_link() { // 創建一個頭結點,頭結點不需要添加任何數據 struct LinkNode *header = malloc(sizeof(struct LinkNode)); header->data = 0; header->next = NULL; struct LinkNode *p_end = header; // 創建一個尾指針 int val = -1; while (1) { scanf("%d", &val); // 輸入插入的數據 if (val == -1) // 如果輸入-1說明輸入結束瞭 break; // 先創建新節點 struct LinkNode *newnode = malloc(sizeof(struct LinkNode)); newnode->data = val; newnode->next = NULL; // 將節點插入到鏈表中 p_end->next = newnode; // 更新尾部指針指向 p_end = newnode; } return header; } // 遍歷鏈表 int foreach_link(struct LinkNode *header) { if (NULL == header || header->next == NULL) return 0; while (header->next != NULL) { printf("%d \n", header->data); header = header->next; } return 1; } // 在header節點中oldval插入數據 void insert_link(struct LinkNode *header,int oldval,int newval) { struct LinkNode *pPrev = header; struct LinkNode *Current = pPrev->next; if (NULL == header) return; while (Current != NULL) { if (Current->data == oldval) break; pPrev = Current; Current = Current->next; } // 如果值不存在則默認插入到尾部 //if (Current == NULL) // return; // 創建新節點 struct LinkNode *newnode = malloc(sizeof(struct LinkNode)); newnode->data = newval; newnode->next = NULL; // 新節點插入到鏈表中 newnode->next = Current; pPrev->next = newnode; } // 清空鏈表 void clear_link(struct LinkNode *header) { // 輔助指針 struct LinkNode *Current = header->next; while (Current != NULL) { // 保存下一個節點地址 struct LinkNode *pNext = Current->next; printf("清空數據: %d \n", Current->data); free(Current); Current = pNext; } header->next = NULL; } // 刪除值為val的節點 int remove_link(struct LinkNode *header, int delValue) { if (NULL == header) return; // 設置兩個指針,指向頭結點和尾結點 struct LinkNode *pPrev = header; struct LinkNode *Current = pPrev->next; while (Current != NULL) { if (Current->data == delValue) { // 刪除節點的過程 pPrev->next = Current->next; free(Current); Current = NULL; } } // 移動兩個輔助指針 pPrev = Current; Current = Current->next; } // 銷毀鏈表 void destroy_link(struct LinkNode *header) { if (NULL == header) return; struct LinkNode *Curent = header; while (Curent != NULL) { // 先來保存一下下一個節點地址 struct LinkNode *pNext = Curent->next; free(Curent); // 指針向後移動 Curent = pNext; } } // 反響排序 void reverse_link(struct LinkNode *header) { if (NULL == header) return; struct LinkNode *pPrev = NULL; struct LinkNode *Current = header->next; struct LinkNode * pNext = NULL; while (Current != NULL) { pNext = Current->next; Current->next = pPrev; pPrev = Current; Current = pNext; } header->next = pPrev; } int main(int argc, char* argv[]) { struct LinkNode * header = init_link(); reverse_link(header); foreach_link(header); clear_link(header); system("pause"); return 0; }
以下代碼來源於網絡
技巧01:冒泡排序
#include <stdio.h> int main(int argc, char *argv[]) { int i,j,t,a[11]; printf ("please input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); for(i=1;i<10;i++) //i代表比較的趟數 for(j=1;j<11-i;j++) //j代表每趟兩兩比較的次數 if (a[j]>a[j+1]) { t=a[j]; a[j]=a[j+1]; a[j+1]=t; } printf ("the sorted numbers:\n"); for(i=1;i<=10;i++) printf ("%5d",a[i]); return 0; }
技巧02:選擇排序
#include <stdio.h> int main(int argc, char *argv[]) { int i,j,t,a[11]; printf ("please input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); for(i=1;i<=9;i++) for(j=i+1;j<=10;j++) if (a[i]>a[j]) { t=a[i]; a[i]=a[j]; a[j]=t; } printf ("the sorted numbers:\n"); for(i=1;i<=10;i++) printf ("%5d",a[i]); return 0; }
技巧03:直接插入排序
#include <stdio.h> void insort(int s[],int n) { //數組的下標從2開始,0做監視哨,1 一個數據無可比性 int i,j; for (i=2; i<=n; i++) { s[0]=s[i]; j=i-1; while(s[0]<s[j]) { s[j+1]=s[j]; j--; } s[j+1]=s[0]; } } int main(int argc, char *argv[]) { int a[11],i; printf ("please input number:\n"); for(i=1;i<=10;i++) scanf("%d",&a[i]); printf ("the original order:\n"); for(i=1;i<11;i++) printf ("%5d",a[i]); insort(a,10); printf ("\nthe sorted numbers:\n"); for(i=1;i<11;i++) printf ("%5d",a[i]); return 0; }
技巧04:歸並排序
#include <stdio.h> void merge(int r[],int s[],int x1,int x2,int x3) { //實現一次歸並排序函數 int i,j,k; i=x1; //第一部分的開始位置 j=x2+1; //第二部分的開始位置 k=x1; while((i<=x2)&&(j<=x3)) //當i和j都在兩個要合並的部分中 if (r[i]<=r[j]) //篩選兩部分中較小的元素放到數組s中 { s[k]=r[j]; i++; k++; } else { s[k]=r[j]; j++; k++; } while(i<=x2) //將x1,x2范圍內的未比較的數順次加到數組r中 s[k++]=r[i++]; while(j<=x3) //將x2,x3范圍內的未比較的數順次加到數組r中 s[k++]=r[j++]; } void merge_sort(int r[],int s[],int m,int n) { int p; int t[20]; if(m==n) s[m]=r[m]; else { p=(m+n)/2; merge_sort(r,t,m,p); //遞歸調用merge_sort函數將r[m],r[p]歸並成有序的t[m],t[p] merge_sort(r,t,p+1,n); //遞歸調用merge_sort函數將r[p+1],r[n]歸並成有序的t[p+1],t[n] merge(t,s,m,p,n); //調有函數將前兩部分歸並到s[m],s[n] } } main() { int a[11]; int i; printf ("please input 10 numbers:\n"); for(i=1;i<=10;i++) //從鍵盤中輸入10個數 scanf("%d",&a[i]); merge_sort(a,a,1,10); //調用merge_sort函數進行歸並排序 printf ("the sorted numbers:\n"); for(i=1;i<=10;i++) printf ("%5d",a[i]); //將排序後的結構輸出 return 0; }
技巧05:希爾排序(插入排序的改進)
#include <stdio.h> void shsort(int s[],int n) { int i,j,d; d=n/2; //確定固定增量值 while(d>=1) { for (i=d+1; i<=n; i++) //數組下標從d+1開始進行直接插入排序 { s[0]=s[i]; //設置監視哨 j=i-d; //確定要進行比較的元素的最右邊位置 while((j>0)&&(s[0]<s[j])) { s[j+d]=s[j]; //數據右移 j=j-d; //向左移d個位置 } s[j+d]=s[0]; //在確定的位置插入s[i] } d=d/2; //增量變為原來的一半 } } int main(int argc, char *argv[]) { int a[11],i; printf ("please input numbers:\n"); for(i=1;i<=10;i++) scanf("%d",&a[i]); shsort(a,10); printf ("the sorted numbers:\n"); for(i=1;i<=10;i++) printf ("%5d",a[i]); return 0; }
技巧06:快速排序(冒泡排序的改進)
主要的算法思想是在帶排序的n個數據中取第一個數據作為基準值,將所有的記錄分為3組,使得
第一組中各數據值均小於或等於基準值,第二組便是做基準值的數據,第三組中個數舉值均大於
或等於基準值。這便實現瞭第一趟分隔,然後再對第一組和第三組分別重復上述方法。
#include <stdio.h> void qusort(int s[],int start,int end) { //自定義快排函數 int i,j; i=start; j=end; s[0]=s[start]; //設置基準值 while(i<j) { while(i<j&&s[0]<s[j]) j--; //位置左移 if (i<j) { s[i]=s[j]; //將s[j]放到s[i]的位置上 i++; //位置右移 } while(i<j&&s[i]<=s[0]) i++; //位置右移 if (i<j) { s[j]=s[i]; //將大於基準值的s[j]放到s[i]位置 j--; //位置右移 } } s[i]=s[0]; //將基準值放入指定位置 if(start<i) qusort(s,start,j-1); //對分隔出的部分遞歸調用函數qusort() if(i<end) qusort(s,j+1,end); } int main(int argc, char *argv[]) { int a[11],i; printf ("please input numbers:\n"); for(i=1;i<=10;i++) scanf("%d",&a[i]); qusort(a,1,10); printf ("the sorted numbers:\n"); for(i=1;i<=10;i++) printf ("%5d",a[i]); return 0; }
技巧07:順序查找
#include <stdio.h> void search(int key,int a[],int n) { int i,count = 0,count1=0; for (i=0; i<n; i++) { count++; if (a[i]==key) { printf ("serch %d times a[%d]=%d\n",count,i,key); count1++; } } if(count1==0) printf ("no found!\n"); } int main(int argc, char *argv[]) { int n,key,a[100],i; printf ("please input the length of array:\n"); scanf("%d",&n); printf ("please input element:\n"); for(i=0;i<n;i++) scanf("%d",&a[i]); printf ("please input the number which do you want to search:\n"); scanf("%d",&key); search(key,a,n); return 0; }
技巧08:二分查找
#include <stdio.h> void binary_search(int key,int a[],int n) { int low,high,mid,count=0,count1=0; low = 0; high = n-1; while(low<high) { count++; //記錄查找次數 mid=(low+high)/2; //求出中間位置 if(key<a[mid]) //當key小於中間值 high=mid-1; //確定左子表范圍 else if(key>a[mid]) //當key大於中間值 low=mid+1; //確定右子表范圍 else if(key==a[mid]) //當key等於中間值證明查找成功 { printf ("success!\nsearch %d times! a[%d]=%d\n",count,mid,key); count1++; //count1記錄查找成功次數 break; } } if(count1==0) printf ("no found!\n"); } int main(int argc, char *argv[]) { int i,key,a[100],n; printf ("please input the length of array:\n"); scanf("%d",&n); printf ("please input the element:\n"); for(i=0;i<n;i++) scanf("%d",&a[i]); printf ("please input the number which do you want to serch:\n"); scanf("%d",&key); binary_search(key,a,n); return 0; }
技巧09:分塊查找
#include <stdio.h> struct index //定義塊的結構 { int key; int start; int end; }index_table[4]; //定義結構體數組 int block_search(int key,int a[]) //自定義實現分塊查找 { int i,j; i=1; while(i<=3&&key>index_table[i].key) //確定在哪個塊中 i++; if(i>3) //大於分得的塊數,則返回0 return 0; j=index_table[i].start; //j等於塊范圍的起始值 while(j<=index_table[i].end&&a[j]!=key) //在確定的塊內進行查找 j++; if(j>index_table[i].end) //如果大於塊范圍的結束值,則說明沒有要查找的數 j=0; return j; } int main(int argc, char *argv[]) { int i,j=0,k,key,a[16]; printf ("please input the number:\n"); for(i=1;i<16;i++) scanf("%d",&a[i]); for (i=1; i<=3; i++) { index_table[i].start=j+1; //確定每個范圍的起始行 j=j+1; index_table[i].end=j+4; //確定每個塊范圍的結束值 j=j+4; index_table[i].key=a[j]; //確定每個塊范圍中元素的最大值 } printf ("please inpu the number whick do you want to search:\n"); scanf("%d",&key); k=block_search(key,a); if(k!=0) printf ("success ! the position is :%d\n",k); else printf ("no found!\n"); return 0; }
技巧10:哈系查找(沒能很好的運行)
#include <stdio.h> #include <time.h> #define Max 11 #define N 8 int hashtable[Max]; int func(int value) { return value % Max; //哈希函數 } int search(int key) //自定義函數實現哈希函數 { int pos,t; pos=func(key); //哈希函數確定出的位置 t=pos; //t存放確定出的位置 while(hashtable[t]!=key && hashtable[t]!=-1) //如果該位置上不等與要查找的關鍵字且不為空 { t=(t+1)%Max; //利用線性探測求出下一個位置 if(pos==t) //如果經多次探測又回到原來用哈希函數求出的位置則 //說明要查找的數不存在 return -1; } if(hashtable[t]==-1) //如果探測的位置是-1則說明要查找的數不存在 return 0; else return t; } void creathash(int key) //自定義函數創建哈系表 { int pos,t; pos = func(key); //哈希函數確定元素的位置 t = pos; while(hashtable[t]!=-1) //如果該位置有元素存在則在則進行線性探測再散列 { t=(t+1)%Max; if(pos==t) //如果沖突處理後確定的位置與原位置相同則說明哈系表已滿 { printf ("hash table is full\n"); return ; } } hashtable[t]=key; //將元素放入確定的位置 } int main(int argc, char *argv[]) { int flag[50]; int i,j,t; for(i=0;i<Max;i++) hashtable[i]=-1; //哈希表中初始化位置全置-1 for(i=0;i<50;i++) flag[i]=0; //50以內所有數未產生時均標志為0 rand((unsigned long)time(0)); //利用系統時間做種子產生隨機數 i=0; while(i != N) { t=rand()%50; //產生一個50以內的隨機數附給t if (flag[t]=0) //查看t是否產生過 { creathash(t); //調用函數創建哈希表 printf ("%2d:\n",t); //將該元素輸出 for (j=0; j < Max; j++) printf ("(%2d) \n",hashtable[j]); //輸出哈希表的內容 printf ("\n"); flag[t]=1; //將產生的這個數標志為1 i++; //i自加 } } printf ("please input number whick do you want to search:\n"); scanf("%d",&t); //輸入要查找的元素 if (t>0&&t<50) { i=search(t); //調用search進行哈系查找 if(i != -1) printf ("success! the position is:%d\n",i); //若找到該元素則輸出其位置 else printf ("sorry,no found!\n"); //未找到輸出提示信息 } else printf ("input error!\n"); return 0; }
文章出處:https://www.cnblogs.com/lyshark
以上就是C/C++ 常用排序算法整理匯總分享的詳細內容,更多關於C/C++ 排序算法的資料請關註WalkonNet其它相關文章!