幾種基本排序的實現:選擇排序,冒泡排序,插入排序,堆排序,快速排序,歸併排序


//冒泡排序
#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// 冒泡排序
int main1()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);

int i,j;
// 外層循環控制輪數,每一輪找出一個最大的樹沉底
for (i = 0; i < len -1; i++)
{
// 內層循環控制每一輪比較的次數
for (j = 0; j < len-1-i; j++)
{
if (a[j] > a[j+1])
{
swap (a, j, j+1);
}
}
}

printA (a, len);

return 0;
}




// 雞尾酒排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);



int i;
int left  = 0;
int right = len - 1;


while (left < right)
{
// 從左往右找到一個最大的數放到right的位置
for (i = left; i < right; i++)
{
if (a[i] > a[i+1])
{
swap (a, i, i+1);
}
}
right--;     

// 從右往左找到一個最小的數放到left的位置
for (i = right; i > left; i--)
{
if (a[i-1] > a[i])
{
swap (a, i, i-1);
}
}
left++;
}


printA (a, len);

return 0;
}







//選擇排序
#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}

int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);

int i,j;
int min;
// 外層循環控制輪數,每一輪找到一個最小的數
for (i = 0; i < len-1; i++)
{
min = i;    
// 內層循環找每一輪最小數的下標
for (j = i+1; j < len; j++)
{
if (a[min] > a[j])
{
min = j;    // 保存當前最小元素的下標
}
}

// 如果當前頂端元素不是最小的值,將最小的值和頂端元素進行交換
if (min != i)
{
swap (a, i, min);
}
}

printA (a, len);

return 0;
}





//插入排序
#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// 插入排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);

int get;   // 抓牌
int i,j;
for (i = 1; i < len; i++)
{
get = a[i];         // 抓牌
j = i - 1;

// 找到第一個比抓到的牌小的元素,並且進行移位
while (j >= 0 && a[j] > get)
{
a[j+1] = a[j];     // 如果元素比新抓到的元素大,往後移一個位置
j--;
}
a[j+1] = get;          // 將新元素插入第一個比它小的元素的後面
}

printA (a, len);

return 0;
}

//二分法插入排序
#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// 二分插入排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);

int left, right,mid,i,j,get;

for (i = 1; i < len; i++)
{
get = a[i];          // 抓牌
left = 0;            // 確定左邊界
right = i - 1;       // 確定右邊界

// 找插入位置:查找完後要插入的位置在下標爲left的位置
while (left <= right)
{
mid = (left + right)/2;
if (a[mid] > get)     // 要插入的位置在mid的左邊
{
right = mid - 1;  // 重新設定右邊界
}
else                  // 要插入的位置在mid的右邊
{
left = mid + 1;   // 重新設定左邊界
}
}

// 移位操作:將left開始右邊的所有元素都右移一位
for (j = i-1; j >= left; j--)
{
a[j+1] = a[j];
}

a[left] = get;     // 插入新元素
}

printA (a, len);

return 0;
}



//希爾排序

#include <stdio.h>

void swap(int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
void printA(int *a, int len)
{
int i;
for(i=0; i<len; i++)
{
printf("%4d",a[i]);
}
printf("\n");
}
int main()
{
int a[10] = {7,9,6,8,1,4,0,3,2,5};
int len = sizeof(a)/sizeof(a[0]);
int i,j,get;
int d = len;
do
{
d = d/3 + 1;
for(i=d; i<len; i++)
{
get = a[i];
j = i-d;
while(j>=0 && a[j]>get)
{
a[j+d] = a[j];
j -= d;
}
a[j+d] = get;
}
}while(d > 1);
printA(a,len);
return 0;
}






//堆排序
#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// a 代表一個數組
// i 代表要調整的結點的下標
// len  數組的長度
void heapify(int *a, int i, int len)
{
int left = 2 * i + 1;     // 左孩子結點下標
int right = 2 * i + 2;    // 右孩子結點下標
int max = i;     // 三個節點中最大元素的下標

if (left < len && a[left] > a[max])
max = left;
if (right < len && a[right] > a[max])
max = right;

if (max != i)   // 當前父節點不是所有結點中最大的元素,需要做調整
{
swap (a, i, max);
heapify (a, max, len);   // 調整被交換的結點
}
}


void heapSort (int *a, int len)
{
// 建堆
int i;
for (i = len/2 - 1; i >= 0; i--)
{
heapify (a, i, len);
}

// 排序
for (i = len-1; i > 0; i--)
{
swap (a, 0, i);       // 拿堆頂元素與隊尾元素進行交換
len--;                // 找到一個最大元素以後堆大小減1
heapify (a, 0, len);  // 調整堆頂元素
}
}


int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);

heapSort(a, len);

printA (a, len);

return 0;
}






//快速排序
#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// 分區操作,返回基準值的下標
int partition(int *a, int left, int right)
{
int pivot = a[right];
int index = left;   // 如果找到一個比基準值小的元素,與下標爲index的元素交換
int i;
for (i = left; i < right; i++)
{
if (a[i] < pivot)
{
swap (a, i, index);
index++;
}
}
swap (a, index, right);

return index;   // 基準值所在位置下標
}


void qSort(int *a, int left, int right)
{
if (left < right)
{
int pivot = partition(a, left, right);  // 進行分區操作,找基準值下標
qSort (a, left, pivot-1);     // 對左邊部分進行快速排序
qSort (a, pivot+1, right);    // 對右邊部分進行快速排序
}
}


int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);

qSort (a, 0, len-1);

printA (a, len);

return 0;
}




//歸併排序

#include <stdio.h>


// 交換函數
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印數組
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// a 是數組  tmp  是緩衝區
void merge(int *a, int left, int mid, int right, int *tmp)
{
int i = left;
int j = mid + 1;
int k = 0;

while (i <= mid && j <= right)
{
if (a[i] > a[j])
tmp[k++] = a[j++];
else
tmp[k++] = a[i++];
}

while (i <= mid)
tmp[k++] = a[i++];

while (j <= right)
tmp[k++] = a[j++];

k = 0;
for (i = left; i <= right; i++)
{
a[i] = tmp[k++];
}
}


void mergeSort(int *a, int left, int right, int *tmp)
{
if (left >= right)
return;

int mid = (left + right)/2;
mergeSort (a, left, mid, tmp);    // 對左邊部分進行歸併排序
mergeSort (a, mid+1, right, tmp); // 對右邊部分進行歸併排序
merge (a, left, mid, right, tmp); // 將將部分數據進行歸併
}


int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);
int tmp[10];
mergeSort (a, 0, len-1, tmp);
printA (a, len);

return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章