插入排序&堆排序&快速排序實現

爲什麼要排序

1. 有時應用本身就需要對信息進行排序。例如對財務報表進行排序

2. 很多算法通常把排序作爲關鍵子程序,關鍵技術也體現在排序算法中

算法 最壞情況運行時間 平均情況/期望運行時間
插入排序 O(n^2) O(n^2)
堆排序 O(n lgn) --
快速排序 O(n^2) O(n lgn)

1. 插入排序

/*插入排序
  p[] :待排序數組
  len :待排序數組長度
*/
void insertSort(int p[],int len)
{
    int i,pos,cur;

    for (i = 1; i < len; i++)
    {
        pos = i -1 ;    //有序序列的最後一個元素位置
        cur = p[i];     //保存待排序元素的值
        while ( pos >= 0 && p[pos] > cur)   //如果cur值小於有序數組最後一個元素值,則後移有序 
             //數組,再檢查前一個有序數組的值,重複以上循環,直到cur不大於有序數組的值
        {
            p[pos + 1] = p[pos];
            pos--;
        }
        p[pos + 1] = cur;    //將待排序元素插入數組中
    }
}

2. 堆排序

#define INT_MAX  0x7FFFFFFF
#define INT_MIN  (0-INT_MAX)
/*
    最大堆排序  
    a[] :待排序數組
    s :  父節點
    len : 需要排序的堆長度
*/
void HeapAdjustMax(int a[],int s,int len)//一次篩選的過程
{
    int max,tmp;

    while(s <= len/2 -1)
    {
        tmp = (2 * s + 2 >= len) ? INT_MIN : a[2 * s + 2];   // 總數爲偶數,最後一個父節點沒有右孩子
        max = (a[2 * s + 1] >= tmp) ? 2 * s + 1 : 2 * s + 2;  // max 左右孩子中,最大的孩子值

        if(a[max] > a[s])    //大堆小堆比較
        {
            tmp = a[max];
            a[max] = a[s];
            a[s] = tmp;
            s = max;        //交換父節點和子節點的值後,跟蹤到子節點
        }
        else
            break;
    }
}

/*最小堆排序*/
void HeapAdjustMin(int a[],int s,int len)//一次篩選的過程
{
    int min,tmp;

    while(s <= len/2 -1)
    {
        tmp = (2 * s + 2 >= len) ? INT_MAX : a[2 * s + 2];   // 總數爲偶數,最後一個父節點沒有右孩子
        min = (a[2 * s + 1] < tmp) ? 2 * s + 1 : 2 * s + 2;  //// min 左右孩子中,最小的孩子值

        if(a[min] < a[s])    //大堆小堆比較
        {
            tmp = a[min];
            a[min] = a[s];
            a[s] = tmp;
            s = min;        //交換父節點和子節點的值後,跟蹤到子節點
        }
        else
            break;
    }
}
/*
    a[] : 待排序數組
    n   : 數組長度
*/
void HeapSort(int a[],int n)
{
    int temp,i;
    /*n/2-1 爲倒數第一個非葉子節點*/
    for(i = n/2 - 1; i > 0;i--)//通過循環初始化頂堆,最後一個非葉子節點向前找
    {
        HeapAdjustMin(a,i,n); //HeapAdjustMax(a,i,n);
    }
    for(i = n;i > 1;i--)  //末尾向前移動
    {
        HeapAdjustMin(a,0,i);  //HeapAdjustMax(a,i,n);

        temp=a[0];
        a[0]=a[i-1];
        a[i-1]=temp;//交換
    }
}

3. 快速排序

/**************************快速排序法***********************************/
/*
    a[] :待排序數組
    left:左邊界
    right:右邊界
*/
void quickSort(int a[],int left,int right)
{
    int i = left;
    int j = right;
    int temp = a[left];     //此爲基準數
    if(left >= right)
        return;
    while(i != j)
    {
        while(i < j && a[j] >= temp)    //從右向左,找到第一個大於基準數的值,標記
            j--;

        if(j > i)
            a[i] = a[j];                //a[i]已經賦值給temp,所以直接將a[j]賦值給a[i],賦值完之後a[j],有空位

        while(i<j && a[i]<=temp)       //從左向右,找到一個小於基準的數,標記
            i++;
        if(i < j)
            a[j] = a[i];                //交換,將待排序列以基準數分爲左右兩半,分治思想
    }
    a[i]=temp;                          //把基準插入,此時i與j已經相等R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
    quickSort(a,left,i-1);              /*遞歸左邊*/
    quickSort(a,i+1,right);             /*遞歸右邊*/
}

 測試程序

int main()
{
    /* 插入排序*/
    int num[] = {13, 7, 1, 8, 5, 12, 9,6};
    int i;
    int length = sizeof(num)/sizeof(num[0]);


//    insertSort(num,length);   //插入排序
//    HeapSort(num,length);       //堆排序
      quickSort(num,0,length-1);


    for(i=0;i < length;i++)
        printf("%d\t",num[i]);

    return 0;
}

 本文只是算法的實現,具體參考《算法導論》

 

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