自己整理各大排序算法---難免有錯

//*************************************************************************************************************************

***2019年11月25日22:25:51

***這是一個學習的過程!!!

***參考了以下博客,寫的很詳細!!!

***十大排序算法(C++實現): https://blog.csdn.net/mengyujia1234/article/details/90179896

***輕鬆搞定十大排序算法(c++版):https://blog.csdn.net/opooc/article/details/80994353

***史上最容易理解的《十大經典算法(動態圖展示)》:https://blog.csdn.net/wfq784967698/article/details/79551476

***有前人的基礎,我纔有更深層的理解!!!

***以下都是經過自己編譯器實現了的,做個簡單的mark!!!

//**************************************************************************************************************************

/*****************************插入排序*******************************************/
void insertSort(int arr[],int len)
{
    //插入排序的思想:
    /*從第一個元素開始,去除下一個元素,在已經排序的元素中從後向前掃描,如果前的元素大於該元素,
    * 就將其向後移動以爲,直到找到位置
    * */

    for (int i = 1; i < len;i++)
    {
        int preindex;
        int current = arr[i];

        for ( preindex = i - 1;preindex >=0 && arr[preindex] > current;preindex -- ) //找位置
        {
            //前面的大於當前元素
            arr[preindex + 1 ] = arr[preindex]; //將前面的向後移動一位
        }
        //位置找到了,交換
        arr[preindex + 1] = current;
    }
}

/*****************************希爾排序*******************************************/
void shellSort(int arr[],int len)
{
    int gap,i,current,preindex;
    for(gap = len / 2; gap > 0 ; gap = gap / 2) //控制增量
    {
        for(i = gap; i < len; i ++)  //裏面就是一個插入排序
        {
            current = arr[i];
            for(preindex = i - gap;
                preindex >=0 && current <arr[preindex];
                preindex = preindex - gap
                )   //比較大小值
            {
              arr[preindex +gap ] = arr[preindex];
            }
            arr[preindex + gap] = current;
        }
    }
}

/*****************************冒泡排序*******************************************/
void bubleSort(int arr[],int len)
{
    int temp=0;
    for (int first = 0;first <len -1;first ++)
    {
        for (int last = len - 1;last >= first;last --)
        {
            if(arr[last+1 ] < arr[last])   //後面一個比前面一個小,遵循曉得向前跑
            {
                temp = arr[last];
                arr[last] = arr[last+1];
                arr[last+1] = temp;
            }
        }
    }
}
void bubleUpdateSort(int arr[],int len)
{
    int temp=0;
    for (int first = 1;first <len;first ++) //控制趟數
    {
        int flag = 0 ;  //標誌位,
        for (int last = 0;last <len - first;last ++)    //控制交換次數
        {

            if(arr[last+1 ] < arr[last])   //後面一個比前面一個小,遵循小的向前跑
            {
                temp = arr[last];
                arr[last] = arr[last+1];
                arr[last+1] = temp;
                flag = 1;
            }
        }
        if(flag == 0)   //說明這個沒有交換,是有序的
        {
            return;
        }
    }
}

/*****************************快速排序*******************************************/
void quickSort(int arr[],int low,int high)  //書上的,不能很好的理解
{
    int left,right,pivot;
    if(low < high)
    {
        pivot = arr[low];   //選擇基準
        left = low;
        right = high;
        while (left < right)
        {
            while (left < right && arr[right] >= pivot)//找不滿足條件的值,然後停止
            {
                right --;
            }
            if(left < right)
            {
                arr[left++] = arr[right];
            }
            while (left < right && arr[left] <= pivot)//找不滿足條件的值,然後停止
            {
                left ++;
            }
            if(left < right)
            {
                arr[right--] = arr[left];
            }
            arr[left] = pivot;  //基準進行歸爲
            quickSort(arr,low,left-1);
            quickSort(arr,left+1,high);
        }
    }
}
void quick_Sort(int arr[],int left, int right)  //來自網上,比較容易理解
{
    int i, j, t, temp;
    if(left > right)
    {
        return;
    }
    temp = arr[left]; //temp中存的就是基準數
    i = left;
    j = right;
    while(i != j)   //這個是第一遍,完了之後用遞歸執行已經有序的區間,知道全部有序
    {
        //順序很重要,要先從右邊開始找
        while(arr[j] >= temp && i < j)
            j--;
        while(arr[i] <= temp && i < j)//再找右邊的
            i++;
        if(i < j)//交換兩個數在數組中的位置
        {
            t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }
    //最終將基準數歸位
    arr[left] = arr[i];
    arr[i] = temp;
    quick_Sort(arr,left, i-1);//繼續處理左邊的,這裏是一個遞歸的過程
    quick_Sort(arr,i+1, right);//繼續處理右邊的 ,這裏是一個遞歸的過程
}

/*****************************選擇排序*******************************************/
void selectSort(int arr[],int len)
{
    //每次選擇最小的數 並標記其位置
    for(int i = 0;i < len; i++)
    {
        int min=arr[i]; //默認當前爲最小
        int location = i;   //默認標記當前位置
        for(int j = i;j < len; j++)
        {
            if(arr[j] < min)    //如果比min還小,則這個數爲最新的最小值,要保存起來,並標記
            {
                min = arr[j];
                location = j;
            }
        }
        //遍歷完之後 在將arr[i]和最小值進行交換
        arr[location] = arr[i];
        arr[i] = min;
    }
}
/*****************************堆排序*******************************************/
void heapSwap(int *a,int *b)
{
    //使用這個將數組的第一個和最後一個元素進行交換
    int temp;
    temp = *a;
    *a= *b;
    *b = temp;
}
void max_heapify(int arr[], int start, int end)
{
    //建立父節點指標和子節點指標
    int dad = start;
    int son = dad * 2 + 1;
    while (son <= end)  //若子節點指標在範圍內才做比較
    {
        if (son + 1 <= end && arr[son] < arr[son + 1])
        {
            //先比較兩個子節點大小,選擇最大的
            son++;
        }
        if (arr[dad] > arr[son]) //如果父節點大於子節點代表調整完畢,直接跳出函數
        {
            return;
        }
        else  //否則交換父子內容再繼續子節點和孫節點比較
        {
            heapSwap(&arr[dad], &arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
}

void heap_sort(int arr[], int len)
{
    int i;
    //初始化,i從最後一個父節點開始調整
    for (i = len / 2 - 1; i >= 0; i--)
    {
        max_heapify(arr, i, len - 1);
    }

    for (i = len - 1; i > 0; i--)
    {
        heapSwap(&arr[0], &arr[i]); //交換,再重新調整,直到排序完畢
        max_heapify(arr, 0, i - 1); //再重新調整,直到排序完畢
    }
}

/*****************************歸併排序*******************************************/
void merge(int array[],int temp[],int leftpos,int rightpos,int rightEnd)    //將結果進行排序
{
    //這個函數主要是在將有序的數進行合併
    int temppos = leftpos;    //臨時的temp數組中的索引
    int leftEnd= rightpos - 1;    //左邊的末尾端
    int arraylen = rightEnd -leftpos + 1;   //這個是整個數組的長度

    while (leftpos <= leftEnd &&rightpos <= rightEnd)   //只要這個條件滿足,就一直比較左右兩邊值的大小
    {
        if(array[leftpos] < array[rightpos])
        {
            temp[temppos++] = array[leftpos++]; //左邊的小
        }
        else {
            temp[temppos++] = array[rightpos++];    //右邊的小
        }
    }
    //這樣一來,後面的就是剩下的,
    while (leftpos <= leftEnd)
    {
        temp[temppos++] = array[leftpos++]; //把左邊剩餘元素全部放進去
    }
    while (rightpos <= rightEnd)
    {
        temp[temppos++] = array[rightpos++];    //把右邊的剩餘元素全部放進去
    }

    //這樣一來,所有的元素全都在temp臨時數組中排序完成,現在要賦值給原來的數組
    for (int i=0;i<arraylen;i++,rightEnd--)
    {
        array[rightEnd] = temp[rightEnd];
    }

}

void mergerecursive(int array[],int temp[],int low,int high)    //局部函數調用
{
    if(low>=high)
    {
        return;
    }

    //計算分裂點
    int middle= (low+high)/2;
    mergerecursive(array,temp,low,middle);  //把子區間[low,middle]遞歸併排序
    mergerecursive(array,temp,middle+1,high);   //吧把子區間[middle+1,high]遞歸併排序
    merge(array,temp,low,middle+1,high);    //組合,吧兩個有序區間組合爲一個有序區間

}

void mergeSort(int array[],int len)     //整體函數調用
{
    //我要歸併排序,兩個比較
    int *tmp = NULL;
    tmp = new int [len];
    if(tmp!=NULL)
    {
        mergerecursive(array,tmp,0,len-1);
        delete tmp;
    }
}

/*****************************基數排序*******************************************/
int findMax(int array[], int len)
{
   //這個是爲了查找要排序中最大的位數
    int max = 0;
    int count = 1;
    int temp;   //temp來存儲位數
    for(int i = 0; i <len; i++)
    {
        while ((temp/10) != 0)
        {
            temp = array[i] / 10;
            count ++;
        }
        if(count > max)
        {
            max = count;
        }
    }
    return max;     //返回的是最大的位數
}

void baseSort(int array[] ,int len)
{
    int *count = new int[10];  //計數器
    int *temp = new int [len];  //一個桶能裝多少數據
    int maxbit = findMax(array,len);    //先獲得最大位數,最大的位數就是需要排序的次數

    for(int i;i < maxbit;i++)   //比較的次數
    {
        //清空桶中的數據
        for(int i = 0; i < 10; i++)
        {
            count[i] = 0;
        }

        //清空
    }

}

void printSort(int arr[],int len)
{
    for(int j = 0 ;j < len; j++)
    {
        cout << " "<<arr[j];
    }
    cout <<endl;
}

int main()
{
    int array[]={10,9,8,7,6,5,4,3,2,45,58,54,56,8,415,1,5,15,898,545,6,5,4,3,2,1,0,10,9,8,7,6,5,4,3,2,1,0};
    int len = sizeof (array)/sizeof (array[0]);

//    bubleSort(array,len);
//    bubleUpdateSort(array,len);
//    shellSort(array,len);
//    insertSort(array,len);
//    quick_Sort(array,0,9);
//    selectSort(array,len);
//    quickSort(array,0,5);
//    heap_sort(array,len);
    mergeSort(array,len);
    printSort(array,len);

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