排序算法

排序算法

冒泡排序(bubble sort) — O(n^2)


#include <stdio.h>
#define SIZE 8
 
void bubble_sort(int a[], int n);
 
void bubble_sort(int a[], int n)
{
    int i, j, temp;
    for (j = 0; j < n - 1; j++)
        for (i = 0; i < n - 1 - j; i++)
        {
            if(a[i] > a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
            }
        }
}
 
int main()
{
    int number[SIZE] = {95, 45, 15, 78, 84, 51, 24, 12};
    int i;
    bubble_sort(number, SIZE);
    for (i = 0; i < SIZE; i++)
    {
        printf("%d", number[i]);
    }
    printf("\n");

選擇排序


#include <stdio.h>
#include <math.h>
 
#define MAX_SIZE 101
#define SWAP(x, y, t)  ((t) = (x), (x) = (y), (y) = (t))
 
void sort(int[], int);      /* selection sort */
 
void main(void)
{
    int i, n;
    int list[MAX_SIZE];
    printf("Enter the number of numbers to generate: ");
    scanf_s("%d", &n);
    if (n < 1 || n > MAX_SIZE){
        fprintf(stderr, "Improper value of n\n");
        exit(1);
    }
    for (i = 0; i < n; i++){    /* randomly generate numbers */
        list[i] = rand() * 1000;
        printf("%d ", list[i]);
    }
    sort(list, n);
    printf("\n Sorted array:\n");
    for (i = 0; i < n; i++)    /* print out sorted numbers */
        printf("%d ", list[i]);
    printf("\n");
}
 
 
void sort(int list[], int n)
{
    int i, j, min, temp;
    for (i = 0; i < n - 1; i++){
        min = i;
        for (j = i + 1; j < n; j++)
        if (list[j] < list[min])
            min = j;
        SWAP(list[i], list[min], temp);
    }
}

插入排序

有一個(gè)已經(jīng)有序的數(shù)據(jù)序列,要求在這個(gè)已經(jīng)排好的數(shù)據(jù)序列中插入一個(gè)數(shù),但要求插入后此數(shù)據(jù)序列仍然有序,這個(gè)時(shí)候就要用到一種新的排序方法——插入排序法
法一:

voidinsertion_sort(intarray[],intfirst,intlast)
{
inti,j;
inttemp;
for(i=first+1;i<last;i++)
{
temp=array[i];
j=i-1;
//與已排序的數(shù)逐一比較,大于temp時(shí),該數(shù)移后
while((j>=0)&&(array[j]>temp))
{
array[j+1]=array[j];
j--;
}
//存在大于temp的數(shù)
if(j!=i-1)
{array[j+1]=temp;}
}
 
}

法二:

voidinsert_sort(int*array,unsigned int n)
{
int i,j;
int temp;
for(i=1;i<n;i++)
{
temp=*(array+i);
for(j=i;j>0&&*(array+j-1)>temp;j--)
{
*(array+j)=*(array+j-1);
}
*(array+j)=temp;
}
}

合并排序
淺談算法和數(shù)據(jù)結(jié)構(gòu): 三 合并排序
合并排序依賴于合并操作,即將兩個(gè)已經(jīng)排序的序列合并成一個(gè)序列

快速排序

void sort(int *a, int left, int right)
{
    if(left >= right)/*如果左邊索引大于或者等于右邊的索引就代表已經(jīng)整理完成一個(gè)組了*/
    {
        return ;
    }
    int i = left;
    int j = right;
    int key = a[left];
     
    while(i < j)                               /*控制在當(dāng)組內(nèi)尋找一遍*/
    {
        while(i < j && key <= a[j])
        /*而尋找結(jié)束的條件就是,1,找到一個(gè)小于或者大于key的數(shù)(大于或小于取決于你想升
        序還是降序)2,沒(méi)有符合條件1的,并且i與j的大小沒(méi)有反轉(zhuǎn)*/ 
        {
            j--;/*向前尋找*/
        }
         
        a[i] = a[j];
        /*找到一個(gè)這樣的數(shù)后就把它賦給前面的被拿走的i的值(如果第一次循環(huán)且key是
        a[left],那么就是給key)*/
         
        while(i < j && key >= a[i])
        /*這是i在當(dāng)組內(nèi)向前尋找,同上,不過(guò)注意與key的大小關(guān)系停止循環(huán)和上面相反,
        因?yàn)榕判蛩枷胧前褦?shù)往兩邊扔,所以左右兩邊的數(shù)大小與key的關(guān)系相反*/
        {
            i++;
        }
         
        a[j] = a[i];
    }
     
    a[i] = key;/*當(dāng)在當(dāng)組內(nèi)找完一遍以后就把中間數(shù)key回歸*/
    sort(a, left, i - 1);/*最后用同樣的方式對(duì)分出來(lái)的左邊的小組進(jìn)行同上的做法*/
    sort(a, i + 1, right);/*用同樣的方式對(duì)分出來(lái)的右邊的小組進(jìn)行同上的做法*/
                       /*當(dāng)然最后可能會(huì)出現(xiàn)很多分左右,直到每一組的i = j 為止*/
}

計(jì)數(shù)排序(counting sort)

#include<math.h>
testBS()
{
    inta[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
    int *a_p = a;
    //計(jì)算數(shù)組長(zhǎng)度
    intsize = sizeof(a) / sizeof(int);
    //基數(shù)排序
    bucketSort3(a_p, size);
    //打印排序后結(jié)果
    inti;
    for(i = 0; i < size; i++)
    {
        printf("%d\n", a[i]);
    }
    intt;
    scanf("%d", t);
}
//基數(shù)排序
voidbucketSort3(int *p, intn)
{
    //獲取數(shù)組中的最大數(shù)
    intmaxNum = findMaxNum(p, n);
    //獲取最大數(shù)的位數(shù),次數(shù)也是再分配的次數(shù)。
    intloopTimes = getLoopTimes(maxNum);
    inti;
    //對(duì)每一位進(jìn)行桶分配
    for(i = 1; i <= loopTimes; i++)
    {
        sort2(p, n, i);
    }
}
//獲取數(shù)字的位數(shù)
intgetLoopTimes(intnum)
{
    intcount = 1;
    inttemp = num / 10;
    while(temp != 0)
    {
        count++;
        temp = temp / 10;
    }
    returncount;
}
//查詢數(shù)組中的最大數(shù)
intfindMaxNum(int *p, intn)
{
    inti;
    intmax = 0;
    for(i = 0; i < n; i++)
    {
        if(*(p + i) > max)
        {
            max = *(p + i);
        }
    }
    returnmax;
}
//將數(shù)字分配到各自的桶中,然后按照桶的順序輸出排序結(jié)果
voidsort2(int *p, intn, intloop)
{
    //建立一組桶此處的20是預(yù)設(shè)的根據(jù)實(shí)際數(shù)情況修改
    intbuckets[10][20] = {};
    //求桶的index的除數(shù)
    //如798個(gè)位桶index=(798/1)%10=8
    //十位桶index=(798/10)%10=9
    //百位桶index=(798/100)%10=7
    //tempNum為上式中的1、10、100
    inttempNum = (int)pow(10, loop - 1);
    inti, j;
    for(i = 0; i < n; i++)
    {
        introw_index = (*(p + i) / tempNum) % 10;
        for(j = 0; j < 20; j++)
        {
            if(buckets[row_index][j] == NULL)
            {
                buckets[row_index][j] = *(p + i);
                break;
            }
        }
    }
    //將桶中的數(shù),倒回到原有數(shù)組中
    intk = 0;
    for(i = 0; i < 10; i++)
    {
        for(j = 0; j < 20; j++)
        {
            if(buckets[i][j] != NULL)
            {
                *(p + k) = buckets[i][j];
                buckets[i][j] = NULL;
                k++;
            }
        }
    }
}

二叉排序樹或者是一棵空樹,或者是具有下列性質(zhì)的二叉樹:
(1)若左子樹不空,則左子樹上所有結(jié)點(diǎn)的值均小于或等于它的根結(jié)點(diǎn)的值;
(2)若右子樹不空,則右子樹上所有結(jié)點(diǎn)的值均大于或等于它的根結(jié)點(diǎn)的值;
(3)左、右子樹也分別為二叉排序樹;

堆排序
堆排序(Heapsort)是指利用堆積樹(堆)這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法,它是選擇排序的一種。可以利用數(shù)組的特點(diǎn)快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個(gè)節(jié)點(diǎn)的值都不大于其父節(jié)點(diǎn)的值,即A[PARENT[i]] >= A[i]。在數(shù)組的非降序排序中,需要使用的就是大根堆,因?yàn)楦鶕?jù)大根堆的要求可知,最大的值一定在堆頂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,214評(píng)論 0 52
  • 概述:排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,742評(píng)論 0 15
  • 概述排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部的...
    Luc_閱讀 2,292評(píng)論 0 35
  • 來(lái)自微信公眾號(hào):開點(diǎn)工作室(ID:kaidiancs) 排序是根據(jù)某種標(biāo)準(zhǔn)將一組記錄重排的過(guò)程,是最常見的計(jì)算任務(wù)...
    開點(diǎn)工作室閱讀 2,116評(píng)論 0 8
  • 回來(lái)的路上,看到穿著校服的學(xué)生在熙熙攘攘的人群中趕路,表情呆滯,若有所思,連乘務(wù)員說(shuō)話都聽不見最終導(dǎo)致了過(guò)站。這便...
    小小弦子閱讀 188評(píng)論 0 0