C++簡單的幾個排序(冒泡 插入 希爾 快速)

冒泡排序

冒泡排序的基本思想:通過無序區中相鄰記錄關鍵字間的比較和位置的交換,使關鍵字最小的記錄如氣泡一般逐漸往上“漂浮”直至“水面”。

整個算法是從最下面的記錄開始,對每兩個相鄰的關鍵字進行比較,且使關鍵字較小的記錄換至關鍵字較大的記錄之上,使得經過一趟冒泡排序後,關鍵字最小的記錄到達最上端,接着再在剩下的記錄中找關鍵字次小的記錄,並把它換在第二個位置上。依次類推,一直到所有記錄都有序爲止。

**若有 n個數據元素,則比較次數爲:(n-1)n/2
交換次數:
如果序列本身有序,無需交換
如果序列本身倒序,交換(n-1)n/2
因此,冒泡排序的時間複雜度爲O(n^2)
2)穩定性

#include "stdafx.h"

#include<iostream>
#include<string>
using namespace std;
// 冒泡排序
int main()
{
        int list[10] = { 56,98,10,84,19, 53,68,73,34,71 };
        int length = sizeof(list) / sizeof(list[0]);//求數組長度
        cout << length << endl;
        //-----------------------------------------------
        for (int i = 0; i < length-1; i++)
        {
                for (int j = 0; j < length-1-i; j++)
                {
                        if (list[j]>list[j+1])
                        {
                                int temp = list[j];
                                list[j] = list[j + 1];
                                list[j + 1] = temp;
                        }
                }
        }
        for (int i = 0; i < length; i++)
        {
                cout << list[i]<<" ";
        }
    return 0;
}

插入排序

假設待排序的記錄存放在數組R[0…n-1]中,排序過程的某一中間時刻,R被劃分成兩個子區間R[0…i-1]和R[i…n-1],其中:前一個子區間是已排好序的有序區,後一個子區間則是當前未排序的部分,不妨稱其爲無序區。

直接插入排序的基本操作是將當前無序區的第1個記錄R[i]插入到有序區R[0…i-1]中適當的位置上,使R[0…i]變爲新的有序區。

**1)時間複雜度
若有 n個數據元素序列
如果序列本身有序,比較n-1次,交換0次
如果序列本身倒序,比較(n-1)n/2次,交換(n-1)n/2次
所以插入排序的時間複雜度爲O(n2),最優複雜度爲O(n)
2)穩定性

#include "stdafx.h"

#include<iostream>
#include<string>
using namespace std;

int main()
{
        int list[10] = { 56,98,10,84,19, 53,68,73,34,71 };
        int length = sizeof(list) / sizeof(list[0]);//求數組長度
        cout << length << endl;
    
       
        int  key = 0;//監視哨
        for (int i = 0; i < length; i++)
        {
                for (int j = i-1; j >=0; j--)                  //******
                {
                        if (list[j+1]>list[j])
                        {
                        key = list[j + 1];
                        list[j + 1] = list[j];
                        list[j] = key;

                        }
                }
        }
        for (int i = 0; i < length; i++)
        {
                cout << list[i] << "  ";
        }

    return 0;
}



希爾 排序

希爾排序:希爾排序又稱爲縮小增量排序,它是一種插入排序。其基本思想是:

把記錄按步長(增量)分組,對每組記錄採用插入排序方法進行排序;

隨着步長逐漸縮小,所分成的組包含的記錄越來越多,當步長的值減到1時,整個數據合成爲一組;

增量序列的選擇一般依據下面兩點:
1)最後一個增量必須爲1;
2)應該儘量避免序列中的值(尤其是相鄰的值)互爲倍數的情況。
希爾排序的時間性能優於直接插入排序的原因:
1)當數據有序時,插入排序所需的比較和移動次數均較少,複雜度爲O(n)。
2)在希爾排序分組,每組的記錄數目少,使用插入排序速度快,當增量爲1時,數據又接近有序,速度自然快了。因此,希爾排序在效率上較直接插人排序有較大的改進。平均時間複雜度爲O(n^2)。
因爲以增量跳躍分組排序,所以希爾排序不穩定。


#include <iostream>
#include<string>
using namespace std;
/*數組遍歷*/
void ListShow(int list[],int length){
        for(int i=0;i<10;i++){
        cout<<list[i]<<"  ";
        }
        cout<<endl;
}

void ShellSort(int *list,int len){
        int incream=len;//增量
        int i,j;
        int key=0;
        do{
        incream=incream/3;
        for(i=incream;i<len;i++){
                if(list[i]<list[i-incream]){
                        key=list[i];
                        for(j=i-incream;j>=0&&key<list[j];j-=incream){
                                list[j+incream]=list[j];
                                list[j]=key;
                        }
                }
        } 
 
        }while(incream>1);  cout<<"結果:";
ListShow(list,len);
} 
int  main()
{
        int list[10]={56,98,10,84,19, 53,68,73,34,71};
        int length=sizeof(list)/sizeof(list[0]);//求數組的長度,C++固定方式
          ListShow(list,length);
           ShellSort(list,length);
        return 0;
}


快速排序

快速排序的基本思想:在待排序的n個記錄中任取一個記錄,把該記錄放入適當位置後,數據序列被此記錄劃分成兩部分。所有關鍵字比該記錄關鍵字小的記錄放置在前一部分,所有比它大的記錄放置在後一部分,並把該記錄排在這兩部分的中間(稱爲該記錄歸位),這個過程稱作一趟快速排序。 首先對無序的記錄序列進行“一次劃分”,之後分別對分割所得兩個子序列“遞歸”進行快速排序。
設待排序的表有10個記錄,其關鍵字分別爲{6,8,7,9,0,1,3,2,4,5},採用快速排序方法進行排序的詳細過程如下圖所示。

在這裏插入圖片描述

排序步驟:

1**)選取6爲key,先從尾部(high指針)開始查找比key小的數與key交換,然後從頭部(low指針)開始查找比key大的數與key交換,交替進行,直到high指針和low指針相遇,第一趟排序結束,由key將序列分成左右兩個子序列,左邊都比key小,右邊都比key大。
2)以同樣的方法排序左子序列,直到左子序列有序。
3)再以同樣的方法排序右子序列,直到右子序列有序。**

)時間複雜度

現有 n個數據元素序列

首先對整個數列所有元素都比較一次,分成兩個序列,比較的次數爲n

然後再對這兩個子序列排序,假設子序列時間排序爲O(n/2)

則n個元素的時間複雜度=

<=2O(n/2)+n

<=2(2(O(n/4))+n/2))+n=4O(n/4)+2n

<=2(2(2(O(n/8))+n/4)+n/2))+n=8O(n/8)+3n

……

<=n(O(1))+nlog2^n (O(1)=0)

<= nlog2^n

快速排序的時間複雜度爲:O(nlog2^n)

2)穩定性

在實施快速排序的過程中,相同元素的順序過能會因爲在左右兩個序中不斷的改變位置,因此最後的排序結果相同元素的位置有可能發生變化,因此快速排序算法是不穩定的。

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