C/C++ 常用排序算法整理匯總分享
(偽)冒泡排序算法:
相鄰的兩個元素之間,如果反序則交換數(shù)值,直到?jīng)]有反序的記錄為止.
#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次關(guān)鍵字比較,從Array-x+1個記錄中選出關(guān)鍵字最小的記錄,并和第x個記錄交換.
#include <stdio.h>
void SelectSort(int Array[], int ArraySize)
{
int x, y, minimum, temporary;
for (x = 0; x < ArraySize - 1; x++)
{
minimum = x; // 假設(shè)x是最小的數(shù)
for (y = x + 1; y < ArraySize; y++)
{ // 將假設(shè)中的最小值進行比對
if (Array[y] < Array[minimum])
minimum = y;
}
if (minimum != x)
{ // 循環(huán)結(jié)束后進行交換
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;
}
直接插入排序:
該算法將一個記錄插入到已經(jīng)排好序的有序表中,從而得到一個新的,記錄數(shù)增加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; // 設(shè)置排序間隔
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;
}
歸并排序算法:
將數(shù)組拆分成兩部分,然后將每部分再次拆成兩部分,直到無法拆了為止,然后兩兩比較,最后在歸并到一起.
#include <stdio.h>
#define MAXSIZE 10
// 實現(xiàn)歸并,并把最后的結(jié)果存放到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++];
// 最后將歸并后的結(jié)果存入到list1變量中
for (int m = 0; m < (list1_size + list2_size); m++)
list1[m] = temporary[m];
}
// 拆分數(shù)組,拆分以后傳入merging函數(shù)實現(xiàn)歸并
void MergeSort(int Array[], int ArraySize)
{ // 如果大于1則終止拆解數(shù)組
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); // 遞歸拆解數(shù)組1
MergeSort(list2, list2_size); // 遞歸拆解數(shù)組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) // 有時數(shù)組無法整除,我們來處理一下
{
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>
// 定義鏈表節(jié)點類型
struct LinkNode
{
int data;
struct LinkNode *next;
};
struct LinkNode *init_link()
{ // 創(chuàng)建一個頭結(jié)點,頭結(jié)點不需要添加任何數(shù)據(jù)
struct LinkNode *header = malloc(sizeof(struct LinkNode));
header->data = 0;
header->next = NULL;
struct LinkNode *p_end = header; // 創(chuàng)建一個尾指針
int val = -1;
while (1)
{
scanf("%d", &val); // 輸入插入的數(shù)據(jù)
if (val == -1) // 如果輸入-1說明輸入結(jié)束了
break;
// 先創(chuàng)建新節(jié)點
struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
newnode->data = val;
newnode->next = NULL;
// 將節(jié)點插入到鏈表中
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節(jié)點中oldval插入數(shù)據(jù)
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;
// 創(chuàng)建新節(jié)點
struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
newnode->data = newval;
newnode->next = NULL;
// 新節(jié)點插入到鏈表中
newnode->next = Current;
pPrev->next = newnode;
}
// 清空鏈表
void clear_link(struct LinkNode *header)
{
// 輔助指針
struct LinkNode *Current = header->next;
while (Current != NULL)
{
// 保存下一個節(jié)點地址
struct LinkNode *pNext = Current->next;
printf("清空數(shù)據(jù): %d \n", Current->data);
free(Current);
Current = pNext;
}
header->next = NULL;
}
// 刪除值為val的節(jié)點
int remove_link(struct LinkNode *header, int delValue)
{
if (NULL == header)
return;
// 設(shè)置兩個指針,指向頭結(jié)點和尾結(jié)點
struct LinkNode *pPrev = header;
struct LinkNode *Current = pPrev->next;
while (Current != NULL)
{
if (Current->data == delValue)
{
// 刪除節(jié)點的過程
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)
{
// 先來保存一下下一個節(jié)點地址
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;
}
以下代碼來源于網(wǎng)絡(luò)
技巧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代表比較的趟數(shù)
for(j=1;j<11-i;j++) //j代表每趟兩兩比較的次數(shù)
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)
{ //數(shù)組的下標從2開始,0做監(jiān)視哨,1 一個數(shù)據(jù)無可比性
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)
{ //實現(xiàn)一次歸并排序函數(shù)
int i,j,k;
i=x1; //第一部分的開始位置
j=x2+1; //第二部分的開始位置
k=x1;
while((i<=x2)&&(j<=x3))
//當i和j都在兩個要合并的部分中
if (r[i]<=r[j]) //篩選兩部分中較小的元素放到數(shù)組s中
{
s[k]=r[j];
i++;
k++;
}
else
{
s[k]=r[j];
j++;
k++;
}
while(i<=x2) //將x1,x2范圍內(nèi)的未比較的數(shù)順次加到數(shù)組r中
s[k++]=r[i++];
while(j<=x3) //將x2,x3范圍內(nèi)的未比較的數(shù)順次加到數(shù)組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);
//遞歸調(diào)用merge_sort函數(shù)將r[m],r[p]歸并成有序的t[m],t[p]
merge_sort(r,t,p+1,n);
//遞歸調(diào)用merge_sort函數(shù)將r[p+1],r[n]歸并成有序的t[p+1],t[n]
merge(t,s,m,p,n);
//調(diào)有函數(shù)將前兩部分歸并到s[m],s[n]
}
}
main()
{
int a[11];
int i;
printf ("please input 10 numbers:\n");
for(i=1;i<=10;i++) //從鍵盤中輸入10個數(shù)
scanf("%d",&a[i]);
merge_sort(a,a,1,10); //調(diào)用merge_sort函數(shù)進行歸并排序
printf ("the sorted numbers:\n");
for(i=1;i<=10;i++)
printf ("%5d",a[i]); //將排序后的結(jié)構(gòu)輸出
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++) //數(shù)組下標從d+1開始進行直接插入排序
{
s[0]=s[i]; //設(shè)置監(jiān)視哨
j=i-d; //確定要進行比較的元素的最右邊位置
while((j>0)&&(s[0]<s[j]))
{
s[j+d]=s[j]; //數(shù)據(jù)右移
j=j-d; //向左移d個位置
}
s[j+d]=s[0]; //在確定的位置插入s[i]
}
d=d/2; //增量變?yōu)樵瓉淼囊话?
}
}
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個數(shù)據(jù)中取第一個數(shù)據(jù)作為基準值,將所有的記錄分為3組,使得
第一組中各數(shù)據(jù)值均小于或等于基準值,第二組便是做基準值的數(shù)據(jù),第三組中個數(shù)舉值均大于
或等于基準值。這便實現(xiàn)了第一趟分隔,然后再對第一組和第三組分別重復上述方法。
#include <stdio.h>
void qusort(int s[],int start,int end)
{ //自定義快排函數(shù)
int i,j;
i=start;
j=end;
s[0]=s[start]; //設(shè)置基準值
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); //對分隔出的部分遞歸調(diào)用函數(shù)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++; //記錄查找次數(shù)
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記錄查找成功次數(shù)
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 //定義塊的結(jié)構(gòu)
{
int key;
int start;
int end;
}index_table[4]; //定義結(jié)構(gòu)體數(shù)組
int block_search(int key,int a[]) //自定義實現(xiàn)分塊查找
{
int i,j;
i=1;
while(i<=3&&key>index_table[i].key) //確定在哪個塊中
i++;
if(i>3) //大于分得的塊數(shù),則返回0
return 0;
j=index_table[i].start; //j等于塊范圍的起始值
while(j<=index_table[i].end&&a[j]!=key) //在確定的塊內(nèi)進行查找
j++;
if(j>index_table[i].end) //如果大于塊范圍的結(jié)束值,則說明沒有要查找的數(shù)
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; //確定每個塊范圍的結(jié)束值
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; //哈希函數(shù)
}
int search(int key) //自定義函數(shù)實現(xiàn)哈希函數(shù)
{
int pos,t;
pos=func(key); //哈希函數(shù)確定出的位置
t=pos; //t存放確定出的位置
while(hashtable[t]!=key && hashtable[t]!=-1)
//如果該位置上不等與要查找的關(guān)鍵字且不為空
{
t=(t+1)%Max; //利用線性探測求出下一個位置
if(pos==t)
//如果經(jīng)多次探測又回到原來用哈希函數(shù)求出的位置則
//說明要查找的數(shù)不存在
return -1;
}
if(hashtable[t]==-1) //如果探測的位置是-1則說明要查找的數(shù)不存在
return 0;
else
return t;
}
void creathash(int key) //自定義函數(shù)創(chuàng)建哈系表
{
int pos,t;
pos = func(key); //哈希函數(shù)確定元素的位置
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以內(nèi)所有數(shù)未產(chǎn)生時均標志為0
rand((unsigned long)time(0)); //利用系統(tǒng)時間做種子產(chǎn)生隨機數(shù)
i=0;
while(i != N)
{
t=rand()%50; //產(chǎn)生一個50以內(nèi)的隨機數(shù)附給t
if (flag[t]=0) //查看t是否產(chǎn)生過
{
creathash(t); //調(diào)用函數(shù)創(chuàng)建哈希表
printf ("%2d:\n",t); //將該元素輸出
for (j=0; j < Max; j++)
printf ("(%2d) \n",hashtable[j]); //輸出哈希表的內(nèi)容
printf ("\n");
flag[t]=1; //將產(chǎn)生的這個數(shù)標志為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); //調(diào)用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++ 常用排序算法整理匯總分享的詳細內(nèi)容,更多關(guān)于C/C++ 排序算法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++語言中std::array的用法小結(jié)(神器用法)
這篇文章主要介紹了C++語言中std::array的用法小結(jié),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11

